Memory Analyzer Tool MAT内存分析

1 安装MAT

MAT是有两种安装方式的,这一点与其他eclipse插件略有不同。

一种安装方式是将MAT当做eclipse的插件进行安装:启动Eclipse --> Help --> Eclipse Marketplace,然后搜索Memory Analyzer,安装,重启eclipse即可。

另外一种安装方式是将MAT作为一个独立的软件进行安装:去官网http://www.eclipse.org/mat/downloads.php,根据操作系统版本下载最新的MAT。下载后解压就可以运行了。

2 修改MAT配置

MAT 软件版本解压后目录内有个MemoryAnalyzer.ini文件,该文件里面有个Xmx参数,该参数表示最大内存占用量,默认为1024m,根据堆转储文件大小修改该参数即可。
1. MemoryAnalyzer.ini中的参数一般默认为-vmargs– Xmx1024m,这就够用了。假如你机器的内存不大,改大该参数的值,会导致MemoryAnalyzer启动时,报错:Failed to create the Java Virtual Machine。
2.当你导出的dump文件的大小大于你配置的1024m(说明1中,提到的配置:-vmargs– Xmx1024m),MAT输出分析报告的时候,会报错:An internal error occurred during: "Parsing heap dump from XXX”。适当调大说明1中的参数即可。

3 获取堆内存dump文件

3.1、查看cpu/内存使用率
top
top -Hp pid

3.2、服务器导出dump文件
jmap:Memory Map for java 生成虚拟机的内存快照heapdump文件
jmap -dump:format=b,file=<dumpfile.hprof> <pid>  
/app/jdk/jdk1.8.0_25/bin/jmap -dump:live,format=b,file=HeapDump.655.20191030.bin 655
jstack:Stack trace for java 显示虚拟机的线程快照(堆栈跟踪工具)
/app/jdk/jdk1.8.0_25/bin/jstack 655 > ThreadDump.655.20191030.dump

3.3、将dump文件从服务器上传至ftp
ftp 10.116.218.80
username:01115479
password:sf123456
put HeapDump.72.655.20191029.bin
put ThreadDump.72.655.20190926.dump

3.4 堆内存dump文件分析

Eclipse Memory Analyzer >  File > Open Heap Dump 选择成的HeapDump.72.655.20191029.bin文件

加载后首页如下图,在首页上比较有用的是Histogram和Leak Suspects。

Memory Analyzer Tool MAT内存分析

点击Leak Suspects会在堆转储文件同目录内生成一个Leak Suspects.zip文件,同时也会从首页跳转到Leak Suspects页面。

解压该文件后可以通过浏览器打开分析结果。

Memory Analyzer Tool MAT内存分析

下面是Leak Suspects页面

Memory Analyzer Tool MAT内存分析

Memory Analyzer Tool MAT内存分析

在Leak Suspects页面会给出可能的内存泄露,如上图所示有三个可能的内存泄露,但是只有第一个是我程序里的,另外两个是jar包或jdk里面的,这个可以不用管。

点击Details进入详情页面。在详情页面Shortest Paths To the Accumulation Point表示GC root到内存消耗聚集点的最短路径,如果某个内存消耗聚集点有路径到达GC root,则该内存消耗聚集点不会被当做垃圾被回收。

Memory Analyzer Tool MAT内存分析

在All Accumulated Objects by Class列举了该对象所存储的所有内容。

Memory Analyzer Tool MAT内存分析

为了找到内存泄露,我获取了两个堆转储文件,两个文件获取时间间隔是一天(因为内存只是小幅度增长,短时间很难发现问题)。对比两个文件的对象,通过对比后的结果可以很方便定位内存泄露。

MAT同时打开两个堆转储文件,分别打开Histogram,如下图。在下图中方框1按钮用于对比两个Histogram,对比后在方框2处选择Group By package,然后对比各对象的变化。不难发现heap3.hprof比heap6.hprof少了64个eventInfo对象,如果对代码比较熟悉的话想必这样一个结果是能够给程序员一定的启示的。而我也是根据这个启示差找到了最终内存泄露的位置。

Memory Analyzer Tool MAT内存分析