线上监控显示jvm老年代内存不足,从gc日志上看到是频繁full gc却无法释放内存,猜测可能存在内存泄露的问题,想要dump一下堆信息定位内存泄露的位置。
使用jmap命令生成dump文件,首先使用jps命令查看jar进程 PID,再使用jmap命令生成dump文件。java_pid.hprof是自定义的dump文件名称。

jmap -dump:format=b,file=java_pid.hprof PID

java_pid.hprof会生成在当前目录下,生成后发现堆文件大小有16个g,拉到本地来分析或者使用图形化软件来分析,下载传输的时间较长,也可能会无法加载,此时准备通过linux 上的mat工具进行分析,将dump文件传输到linux服务器上,下载mat工具。

Memory Analyzer的下载地址

根据jdk版本下载合适的mat版本,可以通过uname -a命令查看服务器的操作系统版本号,我们使用的是jdk1.8,x86_64,所以下载的是图示的版本。
在这里插入图片描述
下载后将zip文件放到服务器上,使用unzip命令进行解压,MemoryAnalyzer.ini配置文件上默认的堆内存大小是1024m,需要修改成比dump文件大小大一些,我们这边设置为-Xmx20480m,同时需要注意进行分析的服务器的内存也需要大于你设置的堆内存,不然会出现报错。

[Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000594280000, 696254464, 0) failed; error='Cannot allocate memory' (errno=12)

如果本机有多个jdk,MemoryAnalyzer.ini也可以指定jdk版本,在文件最前配置jdk路径

-vm
/opt/soft/jdk/jdk1.8.0_66/bin/java

准备工作就绪执行分析命令,分析完成会生成很多文件在dump文件所在的目录下,最好新增一个文件夹存储,以防文件太多错乱。

./ParseHeapDump.sh  java_pid.hprof  org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components

org.eclipse.mat.api:suspects 表示生成内存泄露报告
org.eclipse.mat.api:overview 表示生成概述报告
org.eclipse.mat.api:top_components 表示生成大对象报告

分析完成后会生成三个jar包都比较小,可以直接下载到本地查看,java_pid_System_Overview.zip,java_pid_Top_Components.zip,java_pid_Leak_Suspects.zip,我们排查内存泄露问题可以主要看java_pid_Leak_Suspects.zip这个压缩包下的内容。点击detail,划到页面最下方可以看到thread stack,定位到具体代码位置,再实际排查代码问题。
在这里插入图片描述
在这里插入图片描述

Logo

更多推荐