生产环境中,一旦出现内存泄漏,长期运行下非常容易引发内存溢出(OutOfMemory,OOM)故障。为此,JDK 提供了一些内存泄漏的分析工具,如 jconsole,jvisualvm 等,用于辅助开发人员定位问题,但是这些工具很多时候并不足以满足快速定位的需求。
1.Heap Dump的生成
Linux 下使用 jmap 命令生成 Heap Dump:
# java -version // 检验java环境
# jps // 显示当前所有 JVM 进程 pid 的命令
# jmap -dump:live,format=b,file=/dump/heap-dump.hprof <pid> // 比较耗时, 耐心等待
其中的 pid 是 JVM 的进程 id,/dump/heap-dump.hprof 是生成 dump 文件的目录和名称。
2.MAT的使用
MAT 工具是 Eclipse 的一个插件,可以单独使用,使用起来非常方便,尤其是在分析大内存的 dump 文件时,可以非常直观的看到各个对象在堆空间中所占用的内存大小、类实例数量、对象引用关系、利用 OQL 对象查询,以及可以很方便的找出对象 GC Roots 的相关信息,当然最吸引人的还是能够快速为开发人员生成内存泄露报表,方便定位问题和分析问题。
下载安装 MAT https://www.eclipse.org/mat/downloads.php。
当成功启动 MAT 后,通过菜单选项 “File -> Open Heap Dump…” 打开指定的 dump 文件后,将会生成 Overview 选项,如下所示:
顶部功能区说明:
功能说明 | |
Overview | 显示概要信息,并展示了一些常用功能的入口。 |
OQL | MAT 提供了一个对象查询语言(OQL),类似于 SQL,将类当作表,对象当作记录行,成员变量当作表中的字段。 |
Thread Overview | 此工具可以查看生成Heap Dump文件的时候线程的运行情况,用于线程的分析。 |
Run Expert System Test | 可以查看分析完成的HTML形式的报告,也可以打开已经产生的分析报告文件。 |
Open Query Browser | 提供了在分析过程中用到的工具。 |
Find Object by address | 通过十六进制的地址查找对应的对象。 |
Overview 常用功能入口说明:
功能说明 | |
Histogram | 直方图,可以查看每个类的实例的数量和大小。 |
Dominator Tree | 支配树,列出 Heap Dump 中处于活跃状态中的最大的几个对象,默认按 retained size 进行排序,因此很容易找到占用内存最多的对象。 |
Top Consumers | 按类、类加载器和包分别进行查询,并以饼图的方式列出最大的几个对象。 |
Duplicate Classes | 列出被加载多次的类,结果按类加载器进行分组,目标是加载同一个类多次被类加载器加载。使用该工具很容易找到部署应用的时候使用了同一个库的多个版本。 |
Leak Suspects | Run Expert System Test报告的一种,该报告分析了 Heap Dump并尝试找出内存泄漏点,最后在生成的报告中对检测到的可疑点做了详细的说明。 |
Top Components | 列出占用总堆内存超过 1% 的对象。 |