如何分析巨大的 Java heap dump
当要分析一个很大的jvm heap dump时,比如说20多G,从服务器下载下来就需要很久,还要考虑自己主机的内存够不够。
Eclipse Memory Analyzer(MAT)可以用来完成这件令人头疼的事,这里我们不使用Eclipse的UI,直接使用MAT提供的一个脚本来解析heap dump,生成HTML文件的报告,这些报告可以下载到本地或者通过web服务器来浏览。如果是64位的CentOS操作系统,通过如下地址下载MAT:
Linux (x86_64/GTK+)
下载之后,直接解压,接入解压目录,有一个配置文件MemoryAnalyzer.ini,更改配置文件,设置一个比较大的heap以便能够加载dump:
1 | -startup |
运行MAT来分析具体的heap dump:
1 | ./ParseHeapDump.sh ../heap-dump/jvm.hprof |
这一步执行时间会较长,会在heap dump当前目录下生成一些索引和其他文件,以提高分析的速度。在完成这步之后,我们再执行以下命令,来生成”Leak suspects”报告:
1 | ./ParseHeapDump.sh ../heap-dump/jvm.hprof org.eclipse.mat.api:suspects |
这步执行完会生成一个压缩文件jvm_Leak_Suspects.zip,里面是HTML文件,通过这些文件即可像MAT Eclipse UI一样浏览分析报告了。
还可以执行以下选项来看其他一些报告:
1 | org.eclipse.mat.api:suspects |
那如何获取java heap dump呢?
- jmap几个选项参数解释如下:
1
jmap -dump:[live],format=b,file=<file-path> <pid>
- live: if set it only prints objects which have active references and discards the ones that are ready to be garbage collected. This parameter is optional
- format=b: specifies that the dump file will be in binary format. If not set the result is the same
- file: the file where the dump will be written to
- pid: id of the Java process
jcmd
1
jcmd <pid> GC.heap_dump <file-path>
启动参数配置
1
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<file-or-dir-path>
当程序出现java.lang.OutOfMemoryError异常时才会dump heap,同时会出现如下日志:
1
2
3
4
5java.lang.OutOfMemoryError: Requested array size exceeds VM limit
Dumping heap to java_pid12587.hprof ...
Exception in thread "main" Heap dump file created [4744371 bytes in 0.029 secs]
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at com.baeldung.heapdump.App.main(App.java:7)产品环境推荐加上这个配置,对资源没有额外的损耗。
jmx和jconsole
如果需要实时查看,开启jmx通过jconsole查看即可。