对于大型服务端应用程序来说,有些内存泄露问题很难在测试阶段发现,此时就需要分析JVM Heap Dump文件来找出问题。随着单机内存越来越大,应用heap也开得越来越大,动辄十几G的Dump也不足为奇了。要快速分析,快速定位问题就必须有给力的工具帮忙,下面我来介绍下常用内存分析工具。内存分析工具 jmap JDK自带的一个工具,是JVM Heap导出的必备工具。 jmap -dump:format=b,file=xxx.bin pid   pid是java程序pid 此命令会将虚拟机heap镜像导成文件。不过jmap也有直接分析功能:jmap –histo pid,如下图。优点是可以直接查看对象的大小和类型,缺点是无法查看详细的对象引用信息。

 
jhat JDK自带的dump文件分析工具,会启动一个webserver,可以直接浏览对象大小、类型及对象引用信息。缺点是对于动辄几十G的dump文件力不从心,分析时间长而且web界面会因为对象太多而无响应或者OOM。 jhat  -J-mx512m -port <端口号:默认为7000> xxx.bin  -mx512m表示所用最大内存512m MAT Eclipse Memory Analyzer是一个非常好用的内存dump文件分析工具,我们可以利用它的Eclipse 插件轻松实现查看对象树、对象大小、生成报告,甚至自动化分析可能出现泄露的对象。关于MAT的使用介绍可以参考:http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/index.html?ca=drs-。 文章中的例子是在windows平台下分析,对于非常大的dump文件就无能为力了。 Linux下使用MAT 对于非常大的dump文件MAT同样有办法分析,有下面几个步骤:

Step 1:下载MAT的Stand-alone Eclipse RCP Applications,下载地址:http://www.eclipse.org/mat/downloads.php。在“Stand-alone Eclipse RCP Applications”中找到适合自己的版本。找一台足够大内存的linux机器,将MAT复制上去。
Step 2:进入mat所在目录,编辑MemoryAnalyzer.ini文件设置最大内存值比如-Xmx9g。
Step 3:执行./ParseHeapDump.sh xxxx.bin 来分析dump文件,MAT的分析速度还是很快的。最终得到以下文件。
 
Step 4:将分析得到的文件包括原dump文件下载回windows平台,打开eclipse插件使用菜单File-->Open Heap Dump打开dump文件即可查看到分析结果。 MAT中我们最常用的是Dominator Tree(List the biggest objects and what they keep alive.)功能来分析较大的objects以及他们之间的引用关系,确定一些对象为什么不会被gc。比如从下面两张图中就可以看出,在两个前后两次的dump文件中HConnectionManager$HConnectionImplementation对象越来越大,这里就有OOM的风险。