对于堆内存溢出和栈内存溢出,在深入理解JVM虚拟机这本书中有相关的定义:
在java虚拟机规范中,对于局部变量空间(这里的局部变量空间指的是java虚拟机中的“栈”或者说java虚拟机栈中局部变量表部分)规定了两种异常状态:如果线程请求的栈深度(栈深度指的是程序递归调用的次数)大于虚拟机所允许的深度,将抛出StackOverflowError;如果虚拟机栈可以动态扩展(当前大部分的java虚拟机都可以动态扩展,只不过虚拟机规范中也允许固定长度的虚拟机栈),如果扩展时无法申请到足够的内参,就会抛出OutOfMemoryError异常。
1.StackOverflowError即堆栈溢出:
一般是出现在递归调用的时候,即:某个函数调用自己或者是调用其他函数后再次调用自己,只要函数之间互相调用能产生循环的则一定是递归调用。例如
private void print(){
print();
}
@org.junit.Test
public void testStackOverflowError(){
print();
}
输出结果如下:
2.OutOfMemoryError内存溢出:
内存溢出一般是出现在申请了较多的内存空间没有释放的情形。比如无限创建新对象且没有及时释放占用的空间,如下所示:
public class HeapOOM {
static class OOMObject{
}
public static void main(String[] args){
List<Object> list = new ArrayList<Object>();
while (true){
list.add(new OOMObject());
}
}
}
结果如下: