今天我们来一起学习一下如何利用MAT(Memory Analyzer Tool)快速的定位Java程序的内存泄漏问题。本文实验环境为Mac下安装独立版的MAT。

先来科普一下MAT:

The Eclipse Memory Analyzer is a fast and feature-rich Java heap analyzer that helps you find memory leaks and reduce memory consumption.Use the Memory Analyzer to analyze productive heap dumps with hundreds of millions of objects, quickly calculate the retained sizes of objects, see who is preventing the Garbage Collector from collecting objects, run a report to automatically extract leak suspects.

Eclipse Memory Analyzer是一个快速的并且功能丰富的Java堆分析工具,旨在帮助你发现内存泄漏问题和减少内存消耗。

使用MAT来分析生产数以亿计的对象堆转储文件,快速计算存活对象的大小,发现谁在阻碍GC回收对象,形成一个报告来自动提取内存泄漏嫌疑对象。

翻译的磕磕巴巴,英文不差的同学直接看英文吧~

安装独立版本的MAT

官网下载Memory Analyzer 1.9.0 Release,下载地址:

https://www.eclipse.org/mat/downloads.php




java内存 system clock Java内存分析工具_dump分析工具

MAT官网下载



下载zip包解压后,即可双击运行应用程序,MAT欢迎页面:




java内存 system clock Java内存分析工具_java内存 system clock_02

MAT欢迎页



点击"How to Get a Heap Dump",会打开一个本地的MAT文档:




java内存 system clock Java内存分析工具_dump分析工具_03

MAT帮助文档



以上,Java Heap Dump分析工具就安装好了,接下来要做的就是来本地创造一个dump文件,来试试这个工具如何使用。

本地获取Heap Dump文件

写一个简单的类并运行来获取Heap Dump文件:




java内存 system clock Java内存分析工具_dump分析工具_04

TestMemortLeak.java



配置一下启动参数:

-Xms128m -Xmx256m -XX:MaxPermSize=256m

-XX:+HeapDumpOnOutOfMemoryError

-XX:HeapDumpPath=/Users/edz/testMemoryLeak

运行main方法会报错如下:




java内存 system clock Java内存分析工具_eclipse占用内存过大_05

获取Heap Dump



Java Heap Dump文件已到手,开始分析!

MAT分析Java Heap Dump文件

MAT打开本地dump文件,选择Leak Suspects Report:




java内存 system clock Java内存分析工具_dump文件分析工具_06

Leak Suspects Report




java内存 system clock Java内存分析工具_eclipse占用内存过大_07

dump文件分析结果总览



大家看到上面的图是不是基本上就可以看见问题点了?已经明确的告诉你问题嫌疑点:(a)235.6M,把配置的启动参数中分配的内存吃没了。

点击黄色区域"See stacktrace"查看堆栈信息:




java内存 system clock Java内存分析工具_dump文件分析工具_08

stacktrace



立刻便能定位程序中内存泄漏的问题代码了。

以上只是实验阶段,那么在生产环境中当我们怀疑线上业务有内存泄漏问题时候怎么办呢?还是需要拿到Java Heap Dump文件,但是这个时候注意了,一定要保留现场的情况下去拿dump文件,否则重启了或者等Full GC了,现场就没有了。

接下来我们介绍如何通过Jmap来获取Java Heap Dump文件。




java内存 system clock Java内存分析工具_eclipse占用内存过大_09

jmap -h



jmap -h查看linux下jmap命令的用法,大家可以看看他的Usage和options介绍以及如何使用,这里就不对每个参数进行详细介绍了。先查看当前运行的java程序的进程Id:

jps、ps -ef|grep java、ps -ef|grep 项目名称 均可

然后获取转储文件:

jmap -dump:live,format=b,file=dump.phrof 31824

大家在使用上述命令时候一定要小心,如果服务器上的JVM heap过大,会造成应用“Stop the World”,建议使用参数的形式,在启动应用程序的时候就把参数带上,这样也会在内存溢出的时候,能够及时的保存线程dump文件。

把服务器上的dump.phrof文件下载到本地用MAT打开,开启你的分析之路吧~