JVM内存分析系列(二)内存溢出的类型分析

启动参数
-server -verbose:gc -Xms10m -Xmx10m -Xss128k -Xloggc:C:/tmp/gc.log -XX:PermSize=5m -XX:MaxPermSize=5m -XX:MaxDirectMemorySize=10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:/tmp

Java堆溢出
              List<Server> list = new ArrayList<Server>();
              while (true) {
                  list.add(new Server());
              }

java.lang.OutOfMemoryError: Java heap space
Dumping heap to C:/tmp\java_pid7032.hprof ...
Heap dump file created [17593217 bytes in 0.173 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2760)
at java.util.Arrays.copyOf(Arrays.java:2734)
at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
at java.util.ArrayList.add(ArrayList.java:351)
at com.chinaso.phl.Server.main(Server.java:29)



虚拟机栈和本地方法栈溢出
    private int stackLength = 1;

    public void stackLeak() {
        stackLength++;
        stackLeak();
    }
    public static void main(String[] args) throws Throwable {
                Server s = new Server();
                try {
                    s.stackLeak();
                } catch (Throwable t) {
                    System.out.println("stack length:" + s.stackLength);
                    throw t;
                }
    }

stack length:1007
Exception in thread "main" java.lang.StackOverflowError
at com.chinaso.phl.Server.stackLeak(Server.java:13)


运行时常量池溢出
                List<String> list = new ArrayList<String>();
                int i = 0;
                while (true) {
                  list.add(String.valueOf(i++).intern());
                }

java.lang.OutOfMemoryError: PermGen space
Dumping heap to C:/tmp\java_pid7448.hprof ...
Heap dump file created [2591479 bytes in 0.050 secs]
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
at java.lang.String.intern(Native Method)
at com.chinaso.phl.Server.main(Server.java:45)

注意:如果写成下面的形式,就是堆溢出了。只有String.intern()方法,是把字符串内容放入常量池并返回。
                List<String> list = new ArrayList<String>();
                int i = 0;
                while (true) {
                  list.add(new String(String.valueOf(i++)));
                }

java.lang.OutOfMemoryError: Java heap space
Dumping heap to C:/tmp\java_pid8228.hprof ...
Heap dump file created [11828134 bytes in 0.151 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2760)
at java.util.Arrays.copyOf(Arrays.java:2734)
at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
at java.util.ArrayList.add(ArrayList.java:351)
at com.chinaso.phl.Server.main(Server.java:46)




方法区溢出
                while (true) {
                    Enhancer enhancer = new Enhancer();
                    enhancer.setSuperclass(OOMObject.class);
                    enhancer.setUseCache(false);
                    enhancer.setCallback(new MethodInterceptor() {
                        @Override
                        public Object intercept(Object obj,
                                                Method method,
                                                Object[] args,
                                                MethodProxy proxy) throws Throwable {
                            return proxy.invokeSuper(obj, args);
                        }
                    });
                    enhancer.create();
                }

java.lang.OutOfMemoryError: PermGen space
Dumping heap to C:/tmp\java_pid6624.hprof ...
Heap dump file created [1357998 bytes in 0.047 secs]
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
at net.sf.cglib.core.EmitUtils.member_switch_helper(EmitUtils.java:690)
at net.sf.cglib.core.EmitUtils.constructor_switch(EmitUtils.java:681)
at net.sf.cglib.proxy.Enhancer.emitNewInstanceMultiarg(Enhancer.java:849)
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:508)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
at com.chinaso.phl.Server.main(Server.java:66)


本机直接内存溢出
        Field unsafeField = sun.misc.Unsafe.class.getDeclaredFields()[0];
        unsafeField.setAccessible(true);
        sun.misc.Unsafe unsafe = (sun.misc.Unsafe) unsafeField.get(null);
        while (true) {
            unsafe.allocateMemory(1024 * 1024);
        }

Exception in thread "main" java.lang.OutOfMemoryError
at sun.misc.Unsafe.allocateMemory(Native Method)
at com.chinaso.phl.Server.main(Server.java:70)


附录
本文只是模拟各种内存溢出的情况,文章追求精简直接,本文不适合初学者,需要有一定的基础,对JVM内存模型有一定的了解。




作者简介
昵称:澳洲鸟
姓名:朴海林
QQ:85977328
MSN:[email protected]

转载请注明出处

你可能感兴趣的:(jvm内存)