用法:
-XX:+HeapDumpOnOutOfMemoryError 当堆抛出OOM错误时,dump出当前的内存堆转储快照。
举个栗子
public class OOM {
static class OOMObject {
}
//-Xmx20M -Xms20M -XX:+HeapDumpOnOutOfMemoryError -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
public static void main(String[] args) {
List<OOMObject> list = new LinkedList<>();
while(true) {
list.add(new OOMObject());
}
}
}
这个例子很简单,就是不断创建OOMObject,加入到list中(为了让GC Roots到对象之间有可达路径,避免被GC),直到堆内存不够时,抛出OOM异常。
运行后,控制台打印信息
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid97312.hprof ...
Heap dump file created [33684485 bytes in 0.424 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.gc.OOM.main(OOM.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
可以看到dump出了hprof文件可供分析,可以用MAT工具进行分析
用MAT打开后,可以看到分析情况
由此也可以知道,是因为list的容量过大而导致OOM,可以根据此来进行优化代码或者JVM参数。
如果是由内存泄漏导致的,也可以通过工具查看泄漏对象到GC Roots的引用链,就能进行相应的分析处理。
另一个与之相关联的参数:
-XX:HeapDumpPath=/temp/
该参数的含义是指定dump的文件目录