jvm常见的oom异常,可以大致分为以下四种情况:
- 堆内存溢出,堆上对象分配空间不足。
- 栈内存溢出,栈内存问题有stackoverflowerror与outofmemoryerror两类,实际演示中stackoverflowerror比outofmemory更容易出现。
- 常量内存溢出
- 直接内存溢出
这四种方式在eclipse中编码,很容易复现,下面来介绍如何复现这四类异常。我们通过四个类分别模拟一种异常。如下图所示:
堆内存:HeapOOM.java
package com.xxx.oom;
import java.util.ArrayList;
import java.util.List;
public class HeapOOM {
static class OOMObject{}
public static void main(String[] args) {
System.out.println("heapoom start.");
List<OOMObject> list = new ArrayList<HeapOOM.OOMObject>();
int count = 0;
while(true){
list.add(new OOMObject());
System.out.println("count : "+(++count));
}
}
}
运行时虚拟机参数设置:-Dfile.encoding=UTF-8 -verbose:gc -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=E:\oomlog -XX:SurvivorRatio=8
运行结果如下:
栈内存:StackOOM.java
package com.xxx.oom;
public class StackOOM {
private int stackDep = 1;
public void stackLeak(){
stackDep++;
stackLeak();
}
public static void main(String[] args) {
StackOOM oom = new StackOOM();
try{
oom.stackLeak();
}catch(Throwable e){
System.out.println("栈深度: " + oom.stackDep);
e.printStackTrace();
}
}
}
运行时虚拟机参数设置:-verbose:gc -Xms10M -Xmx10M -Xss128k -XX:+PrintGCDetails
运行结果如下:
这里需要说明的是,我们的控制台输出错误信息里面显示的是stackoverflowerror,而不是outofmemoryerror,这个在前面提到过,stackoverflowerror比outofmemoryerror更容易出现。
常量:ConstantOOM.java
package com.xxx.oom;
import java.util.ArrayList;
import java.util.List;
public class ConstantOOM {
public static void main(String[] args) {
try {
List<String> list = new ArrayList<String>();
int item = 0;
while(true){
list.add(String.valueOf(item++).intern());
}
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
运行时虚拟机参数设置:-verbose:gc -Xms10M -Xmx10M -Xss128k -XX:+PrintGCDetails
运行结果如下:
直接内存:DirectMemoryOOM.java
package com.xxx.oom;
import java.nio.ByteBuffer;
public class DirectMemoryOOM {
private static final int ONE_MB = 1024*1024*1024;
private static int count = 1;
public static void main(String[] args) {
try {
while(true){
ByteBuffer buffer = ByteBuffer.allocateDirect(ONE_MB);
count++;
}
} catch (Exception e) {
System.out.println("exception occur,instance count : "+count);
e.printStackTrace();
}
}
}
运行时虚拟机参数设置:-verbose:gc -Xms10M -Xmx10M -XX:MaxDirectMemorySize=5M -Xss128k -XX:+PrintGCDetails
运行结果如下:
以上通过代码与打印信息很直观的给我们展示了四类OOM异常,以及出现异常时的打印信息。方便我们了解这四类异常。