在java虚拟机规范中,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError异常的可能。
java堆溢出: java堆用于存储对象实例,只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么对象数量到达最大堆的容量限制后就会产生内存溢出异常。
只要不断地往List里存放数据,就可以使堆溢出。
public class HeapOOM {
static class OOMObject{
}
public static void main(String[] args) {
List<OOMObject> list=new ArrayList<>();
while(true) {
list.add(new OOMObject());
}
}
}
出现java堆溢出时,异常堆栈信息“java.lang.OutOfMemoryError” 会跟着进一步提示“java heap space”.
虚拟机栈和本地方法栈溢出:
如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常
如果虚拟机在扩展栈时无法申请到足够的内存空间,则将抛出OutOfMemoryError异常
在单线程下,无论是由于栈帧太大还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机抛出的都是StackOverflowError异常
public class JavaVMStackSOF {
private int stackLength=1;
public void stackLeak() {
stackLength++;
stackLeak();
}
public static void main(String[] args) {
JavaVMStackSOF oom=new JavaVMStackSOF();
try {
oom.stackLeak();
} catch (Throwable e) {
System.out.println("stack length:"+oom.stackLength);
throw e;
}
}
}