获取 JVM 的 dump 的两种方式。
通过配置 JVM 参数自动导出
在 JVM 启动参数加增加两个参数
1 | 出现 OOME 时生成堆 dump: |
-XX:HeapDumpPath 是指定 dump 输出的目录
手动通过 Jmap 命令导出
第二种是在程序可能发生异常时手动导出
1 | jmap -dump:format=b,file=/var/logs/heap.hprof $PID |
- format=b 表示输出二进制格式
- file 指定输出的文件目录
- PID 表示指定 JVM 进程的 PID
第一种方式是需要等待当前JVM出现问题后才能生成dmp文件,实时性不高,
第二种方式在执行时,JVM是暂停服务的,所以对线上的运行会产生影响,所以建议第一种方式。
dump 分析
dump 的具体分析可能使用工具进行,比如Jprofiler 或者 Eclipse 的 Memory Analyzer Tool 工具,包括 IDEA 中打开 dump 文件也能展示分析
Eclipse Memory Analyzer Tool 展示效果
IDEA 展示效果
超大dump分析
一般导出的dump文件都比较大,在本地分析可能受限于自身电脑性能与内存的原因无法完成。比如dump文件可能有5、6G,也可能有20、30G的大小。
这种情况下我们可以直接在Linux服务器上分析,需要使用Memory Analyzer Tools这个工具。
下载地址:https://www.eclipse.org/mat/downloads.php
历史版本下载地址:https://eclipse.dev/mat/previousReleases.php
下载的时候需要看下自己Linux的版本,下载匹配的版本即可。
1 | [root@KSSHUAT01450 /data]# uname -m |
另外就是需要下载与自己JDK匹配的版本,否则启动报错:
1 | [root@KSSHUAT01450 /data/mat]# ./ParseHeapDump.sh heap.hprof org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components |
如果是JDK8建议去历史版本中下载Memory Analyzer 1.10.0 Release版本,测试可以正常启动。
下载下来是一个Zip压缩包,直接上传到Linux服务器上进行解压。
1 | [root@KSSHUAT01450 /data]# unzip MemoryAnalyzer-1.10.0.20200225-linux.gtk.x86_64.zip |
解压完成会得到一个mat
目录,在该目录下执行命令
1 | [root@KSSHUAT01450 /data]# ./ParseHeapDump.sh heap.hprof org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components |
命令中的heap.hprof
则是我们自己的dump文件,我是把它移动到了Mat目录当中。
如果内存不足可能会报错:java.lang.OutOfMemoryError: Java heap space
需要调整一下Mat工具的堆内存配置,编辑mat目录下的 MemoryAnalyzer.ini ,调整 -Xmx
的参数即可
1 | [root@KSSHUAT01450 /data]# vim MemoryAnalyzer.ini |