public class StackOverflowErrorDemo {public static void main(String[] args) {javaKeeper();}private static void javaKeeper() {javaKeeper();}
}
JVM 虚拟机栈是有深度的,在执行方法的时候会伴随着入栈和出栈,上边的方法可以看到,main 方法执行后不停的递归,迟早把栈撑爆了
Exception in thread "main" java.lang.StackOverflowErrorat oom.StackOverflowErrorDemo.javaKeeper(StackOverflowErrorDemo.java:15)
-Xss
增加线程栈内存空间, 某些正常使用场景需要执行大量方法或包含大量局部变量,这时可以适当地提高线程栈空间限制Java 堆用于存储对象实例,我们只要不断的创建对象,并且保证 GC Roots 到对象之间有可达路径来避免 GC 清除这些对象,那随着对象数量的增加,总容量触及堆的最大容量限制后就会产生内存溢出异常。
Java 堆内存的 OOM 异常是实际应用中最常见的内存溢出异常。
/*** JVM参数:-Xmx12m*/
public class JavaHeapSpaceDemo {static final int SIZE = 2 * 1024 * 1024;public static void main(String[] a) {int[] i = new int[SIZE];}
}
代码试图分配容量为 2M 的 int 数组,如果指定启动参数 -Xmx12m
,分配内存就不够用,就类似于将 XXXL 号的对象,往 S 号的 Java heap space 里面塞。
Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceat oom.JavaHeapSpaceDemo.main(JavaHeapSpaceDemo.java:13)
针对大部分情况,通常只需要通过 -Xmx
参数调高 JVM 堆内存空间即可。如果仍然没有解决,可以参考以下情况做进一步处理:
内存溢出(out of memory),是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个 Integer,但给它存了 Long 才能存下的数,那就是内存溢出。
内存泄露( memory leak),是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
memory leak 最终会导致 out of memory!