
简介
Eclipse 内存分析器(Eclipse Memory Analyzer)是一款快速且功能强大的 Java 堆内存分析工具,可帮助您发现内存泄漏并降低内存消耗。
使用内存分析器,您可以分析包含数亿个对象的堆转储文件,快速计算对象的保留大小(retained sizes),查看哪些对象阻止了垃圾回收器(Garbage Collector)对其进行回收,并运行报告以自动提取潜在的内存泄漏嫌疑对象。
Eclipse Memory Analyzer Tool (MAT)是eclipe发面的jvm运行内存分析工具,可以分析java程序运行中不同线程占用内存的情况,对于分析内存溢出异常定位有很大的帮助。
1。下载安装
下载地址:Memory Analyzer (MAT) Downloads | The Eclipse Foundation
根据不同的需要,个人可以自行下载不同的版本:
1.1 推荐下载Stand-alone Eclipse RCP Applications 独立程序。以下步骤都是用独立安装版本进行说明。
1.2 通过eclipse的扩展功能的方式安装, 又分两种方法:一是通过的eclipse的安装扩展的方法直接添加的装更新网址, 另一种是直接下载zip包到本地,然后再手动安装eclipse扩展。
1.3 当前(2025-8-5)的版本需要JDK17才能运行, 也就是说要在系统装到jdk17方可正常运行MAT
2。布署运行
不管下载的的哪个平台(win/mac/linux)的版本, 都是一个压缩包。解压后进入要目录, 双击可执行文件 MemoryAnalyzer.(exe ..不同平台有不同辍,这都不重要,重要的是运行可执行文件)。
3。 生成需要分析的内存堆
比如我的tomcat程序或者springboot jar包运行时卡住了, 反应极为缓慢或都直接卡死不响应, 怀疑cpu/mem占用过高, 那么我们就需要导出这个运行的程序占用内存堆的数据。
在linux平台用以下方法导出
(1) 通过 “ps”命令可以得到系统各进程cpu/mem占用情况
# ps aux
得到的系统程序运行情况大概如下
可以看到, 列数据依次代表: 用户名, 进程ID,cpu占用率,内存占用率。。。。知道些就可以进行必的筛选了。
比如我们可以通过以下命令筛选占用CPU达到70%以上的java程序(不管tomcat还是 springboot都是java运行的程序)
# ps aux|grep java|awk ‘{if($3>70.0) print $2}’|sed -n 1p
grep 过虑java程序,awk只打印cpu(第三列)占用超过70%的PID号, sed只选第一个,不仅想看第一个,那么可以不加sed过虑。
假如我们等到的PID为12507如下:
当然也可以根据内存占用率来读取PID, 参考命令如下 :
# ps aux|grep java|awk ‘{if($4>40.0) print $2}’|sed -n 1p
$4就是第4列,即内存占用率, 假如系统总内存是8G, 那么大于%40就是占用内存超过3.2G的程序。
如是windows系统运行的java程序, 那查找cpu/内存占用率高的就相对简单了, 打开任务管理器,对进程进行排序即可,如下图:
(2)接下来可以根据pid导出内存堆数据:
# $JAVA_HOME/bin/jmap -dump:format=b,file=/root/heap.12507.hprof 12507
得到文件 /root/heap.12507.hprof
4.分析内存堆
如果linx系统本机已经有桌面(gnome/kde等)直接在linux运行MAT并导入内存堆。如果想下载到windows主机进行分析,堆文件过大时,可以先用tar打包工具压缩打包再下载,下载后再解包。
(1)在MAT导入内存堆
File / Open Heap Dump …
选择上一步导出的hprof文件 ,选择好后会弹出一个选择分析选项, 默认finish。
(2)导入成功后查看“Overview”, 把鼠标移到点用率最高的饼块,可以看到” http-nio-8080-exec-10″这个线程占用了最多的空间内存
(3)分析是哪个类方法处理什么数据导致的占用率高, 点击“Leak Suspects”, 可以看到,这个线程里的某个 java.lang.Object[] 对象占用了大部(83.5%), 接下来看看是哪个类哪个方法处理了什么数据。
(4)堆栈跟踪, 点“See stacktrace”, 排除一些公共类, 可以看到”SoapServiceImpl”的其中一个方法出了问题
(5) 查看是处理哪些数据导致占用内存过高。回到”Overview”标签, 点”Dominator Tree”
来到 dominator_tree标签, 根据线程名称和占比数据, 依次点开, 就可以查看到是处理什么数据了,如下图:
至此, 定位方法和处理数据的内容都已经找到, 然后根据这个结果。 回去优化java代码。