今天我们来一起学习一下如何利用MAT(Memory Analyzer Tool)快速的定位 Java 程序的 内存泄漏 问题。本文实验环境为Mac下安装独立版的MAT。
先来科普一下MAT:
Eclipse Memory Analyzer是一个快速的并且功能丰富的Java堆分析工具,旨在帮助你发现内存泄漏问题和减少内存消耗。
使用MAT来分析生产数以亿计的对象堆转储文件,快速计算存活对象的大小,发现谁在阻碍GC回收对象,形成一个报告来自动提取内存泄漏嫌疑对象。
翻译的磕磕巴巴,英文不差的同学直接看英文吧~
安装独立版本的MAT
官网下载Memory Analyzer 1.9.0 Release,下载地址:
下载zip包解压后,即可双击运行应用程序,MAT欢迎页面:
点击”How to Get a Heap Dump”,会打开一个本地的MAT文档:
以上,Java Heap Dump分析工具就安装好了,接下来要做的就是来本地创造一个dump文件,来试试这个工具如何使用。
本地获取Heap Dump文件
写一个简单的类并运行来获取Heap Dump文件:
配置一下启动参数:
-Xms128m -Xmx25 6M -XX:MaxPermSize=256m
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/Users/edz/testMemoryLeak
运行main方法会报错如下:
Java Heap Dump文件已到手,开始分析!
MAT分析Java Heap Dump文件
MAT打开本地dump文件,选择Leak Suspects Report:
大家看到上面的图是不是基本上就可以看见问题点了?已经明确的告诉你问题嫌疑点:(a)235.6M,把配置的启动参数中分配的内存吃没了。
点击黄色区域”See stacktrace”查看堆栈信息:
立刻便能定位程序中内存泄漏的问题代码了。
以上只是实验阶段,那么在生产环境中当我们怀疑线上业务有内存泄漏问题时候怎么办呢?还是需要拿到Java Heap Dump文件,但是这个时候注意了,一定要保留现场的情况下去拿dump文件,否则重启了或者等Full GC了,现场就没有了。
接下来我们介绍如何通过Jmap来获取Java Heap Dump文件。
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打开,开启你的分析之路吧~