/** * -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError */ public class HeapOOM { static class OOMObject{} public static void main(String[] args) { System.out.println("test"); List<OOMObject> list = new ArrayList<>(); while (true){ list.add(new OOMObject()); } } }
结果
1 2 3
java.lang.OutOfMemoryError: Java heap space Dumping heap to java _pid3404.hprof ... Heap dump file created [22045981 bytes in 0.663 secs]
Exception in thread "main" java.lang.StackOverflowError stack length:2271 at com.laowang.vm.StackOverFlow.stackLeak(StackOverFlow.java:9) at com.laowang.vm.StackOverFlow.stackLeak(StackOverFlow.java:10) at com.laowang.vm.StackOverFlow.stackLeak(StackOverFlow.java:10) at com.laowang.vm.StackOverFlow.stackLeak(StackOverFlow.java:10) 以下省略.....
方法区和运行时常量溢出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/** * VM Args -XX:PermSize=10M -XX:MaxPermSize=10M * jdk1.6以前的版本,常量池分配在永久代,可以使用以上的参数来限值方法区的大小。 * jdk1.7以后逐步 ”去永久代“ */ public class RuntimeConstantPoolOOM { public static void main(String[] args) { //使用List保持着常量池引用,避免Full GC回收常量池行为 List<String> list = new ArrayList<>(); int i = 0; while (true){ //intern()方法的作用是如果常量池中有则返回,如果没有则放入常量池再返回 list.add(String.valueOf(i++).intern()); } } }
结果
1 2 3
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space at java.lang.String.intern(Native method) at com.laowang.vm.RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java:10)
引申:String.intern()返回引用测试
1 2 3 4 5 6 7 8
public class StringIntern { public static void main(String[] args) { String str1 = new StringBuilder("计算机").append("软件").toString(); System.out.println(str1.intern() == str1); String str2 = new StringBuilder("ja").append("va").toString(); System.out.println(str2.intern() == str2); } }
/** * VM Args -XX:PermSize=10M -XX:MaxPermSize=10M * 同样在jdk1.7以后没有效果 * 在jdk1.6以前会出现OOM */ public class JavaMethodAreaOOM { public static void main(final String[] args) { while(true){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(OOMObject.class); enhancer.setUseCache(false); enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { return methodProxy.invokeSuper(objects,args); } }); enhancer.create(); } } static class OOMObject{ } }
结果
1 2 3 4 5
Caused by: java.lang.OutOfMemoryError: PermGen space at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632) at java.lang.ClassLoader.defineClass(ClassLoader.java:616) ... 8 more
本机直接内存溢出
直接内存可以使用 -XX:MaxDirectMemorySize 指定
默认与Java堆最大值( -Xms 指定)一样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/** * VM Args: -Xmx20M -XX:MaxDirectMemorySize=10M */ public class DirectMemoryOOM { private static final int _1MB = 1024 * 1024;
Exception in thread "main" java.lang.OutOfMemoryError at sun.misc.Unsafe.allocateMemory(Native Method) at com.laowang.vm.DirectMemoryOOM.main(DirectMemoryOOM.java:18)