首先,我们说OOM,也就是我们的Java代码可能会导致的计算机各个部分的内存溢出。那么,都有哪些位置容易出现OOM呢?废话少说,我们直接上图。
概览运行时数据区
可以看到,对于我们的Java程序来说,一共就这么多片区域。那么哪些区域会导致内存溢出呢?
栈内存溢出
HotSpot虚拟机中栈的大小是固定的,不支持扩展,但是默认大小都是1M。虽然不支持扩展,但是可以在启动的时候用-Xmx参数设置每一个虚拟机栈的默认值,再启动。
既然栈的大小是固定的,那就有OOM的可能。但是一般我们在开发中,普通方法之间的调用是很难出现OOM的,那么导致栈区OOM的常见原因会是什么呢?
无限递归导致栈OOM
Java.lang.StackOverflowError(单个虚拟机栈)一般普通的方法调用是很难出现的,如果遇到了可能写了无限递归。
虚拟机栈带给我们的启示:方法的执行因为要打包成栈帧。所以天生比面向过程的简单循环要慢。所以树的遍历算法中递归和非递归(这也就是为什么虚拟机优化要朝着方法内联而努力的原因)都有其存在的意义。递归的代码更简洁,非递归代码复制但速度快。
栈内存的OOM(此处指的整个运行时数据区的栈空间)的发生条件是:不断地创建栈帧(方法),就会不断地消耗其所在的虚拟机栈空间。而我们的虚拟机栈满打满算