news 2026/9/8 17:41:09

Eclipse Memory Analyzer(MAT)入门教程:从生成 Heap Dump 到定位 Java 内存问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Eclipse Memory Analyzer(MAT)入门教程:从生成 Heap Dump 到定位 Java 内存问题

在排查 TongWeb、Tomcat、Spring Boot 等 Java 服务的内存问题时,经常会遇到这样的情况:

JVM 内存越来越高 ↓ Full GC 越来越频繁 ↓ GC 后内存仍然降不下来 ↓ 最终 OutOfMemoryError

这时候,仅仅通过topjstat查看 JVM 内存,只能知道“内存有问题”,却很难知道到底是什么对象占用了内存

这时候就可以使用Eclipse Memory Analyzer(MAT)

简单来说:

  • MAT就是一款专门用来分析 Java Heap Dump 的工具,可以帮助我们找到占内存最多的对象,以及这些对象为什么一直没有被 GC 回收。
  • 最主要的是完全免费,不需要进行pojie等操作。

MAT 主要用来解决什么问题?

MAT 最常见的使用场景主要有以下几种:

1. Java 服务频繁 OOM

例如日志出现:

java.lang.OutOfMemoryError: Java heap space

可以在 JVM OOM 后生成的 Heap Dump 中寻找问题。

2. JVM 内存持续上涨

例如:

启动:2G 运行一天:3G 运行三天:5G 运行一周:7G

而且 Full GC 之后内存仍然很高,就需要重点怀疑对象没有正常释放。

3. Full GC 频繁

如果发现 JVM 不断进行 Full GC:

Full GC Full GC Full GC

但是回收效果越来越差,也可以通过 Heap Dump 分析到底是什么对象占用了堆内存。

4. 怀疑内存泄漏

例如:

缓存没有清理 ThreadLocal 使用不当 静态 Map 持有大量对象 Session 保存大量数据 Web 应用重复部署后 ClassLoader 没有释放

这些问题都可以通过 MAT 进一步分析。


MAT 的整体排查思路

第一次使用 MAT,不需要把所有功能都学会。

记住下面这条路线就够了:

第一步:找到服务器上的 Java 进程

首先登录服务器。

执行:

jps -l

例如:

[root@server ~]# jps -l 12345 org.apache.catalina.startup.Bootstrap 13579 sun.tools.jps.Jps

这里:

12345

就是我们需要分析的 Java 进程 PID。


第二步:检查磁盘空间

Heap Dump 可能非常大。

例如:

JVM 最大堆:8G

生成出来的.hprof文件可能达到几个 GB。

所以生成之前建议先执行:

df -h

确认目标磁盘空间足够。

例如:

Filesystem Size Used Avail Use% /dev/sda3 100G 55G 45G 56%


第三步:生成 Heap Dump

现在假设 Java PID 是:

12345

推荐使用jcmd

jcmd 12345 GC.heap_dump /data/dump/tongweb.hprof

也可以使用jmap

jmap -dump:format=b,file=/data/dump/tongweb.hprof 12345

生成成功后会得到:

tongweb.hprof

这个文件就是后面 MAT 分析的对象。


确认文件是否生成成功

执行:

ls -lh /data/dump/tongweb.hprof

例如:

-rw------- 1 root root 4.2G Sep 3 13:20 tongweb.hprof

这里重点看文件大小。

如果发现:

4.2G

说明这个文件比较大,后续下载和 MAT 分析都需要一定时间。


第四步:把 Heap Dump 下载到本地

服务器上的文件一般不建议直接在服务器上分析。

通常是:

服务器 ↓ 生成 hprof ↓ 下载 ↓ 自己的电脑 ↓ MAT 分析

例如 Mac/Linux 可以使用:

scp root@192.168.1.100:/data/dump/tongweb.hprof .

如果 SSH 使用其他端口:

scp -P 2222 root@192.168.1.100:/data/dump/tongweb.hprof .

也可以使用 Xftp、WinSCP、SFTP 等工具传输。


第五步:使用 MAT 打开 Heap Dump

打开 Eclipse Memory Analyzer。

你现在看到的这个界面就是 MAT 的主界面。

然后点击:

File ↓ Open Heap Dump

选择:

tongweb.hprof

也可以直接点击:

Open a Heap Dump

然后选择.hprof文件。


打开之后先看 Overview

Heap Dump 加载完成后,MAT 会展示整体信息。

这里可以先看看:

对象数量 Class 数量 Class Loader 堆内存情况

不用一开始就研究所有数据。

先建立一个概念:

这个 Heap Dump 记录的到底是一个什么样的 JVM 内存现场。


第一项重点分析:Leak Suspects

MAT 通常会提供:

Leak Suspects

可以理解成:

MAT 根据当前 Heap Dump 自动找出来的可疑内存占用点。

例如:

Problem Suspect 1 One instance of xxx retains a large amount of memory

这时候可以继续点击进去查看具体对象和引用关系。

不过要注意:

Leak Suspects 标记出来的对象不一定就是内存泄漏。

比如一个正常的大缓存,本身就可能占用几个 GB。

所以还需要继续分析。


第二项重点分析:Histogram

找到:

Histogram

Histogram 可以简单理解成:

按照 Java 类统计对象数量和内存占用。

例如:

Class Name Objects Shallow Heap ------------------------------------------------------- java.lang.String 3000000 120 MB byte[] 1000000 800 MB java.util.HashMap$Node 900000 30 MB com.xxx.User 500000 40 MB

这里重点观察两个问题:

对象数量是不是异常?

例如:

User:500万 Order:300万 String:1000万

如果业务实际上只有几十万用户,这就值得调查。

哪些对象占用内存最多?

尤其关注:

byte[] char[] String HashMap ConcurrentHashMap 业务自己的对象


第三项重点分析:Dominator Tree

如果想进一步找:

到底是谁“占住”了大量内存?

可以打开:

Dominator Tree

重点关注:

Retained Heap

例如:

com.xxx.Cache 3.2 GB HashMap 2.8 GB com.xxx.UserManager 1.5 GB byte[] 900 MB

这时候:

com.xxx.Cache

就值得重点检查。

因为它自己可能只占几十 MB,但它引用了大量其他对象,最终导致:

Retained Heap = 3.2 GB

这也是 MAT 排查内存问题时非常重要的一个指标。


最后一个关键分析:Path to GC Roots

假设我们发现:

com.xxx.User

占用了大量内存。

接下来最关键的问题是:

为什么这些 User 一直没有被 GC 回收?

可以右键对象,找到:

Path to GC Roots

然后查看引用链。

例如:

GC Root ↓ Thread ↓ ThreadLocalMap ↓ ThreadLocal ↓ User

或者:

GC Root ↓ Static Field ↓ Cache ↓ HashMap ↓ User

这时候就开始接近真正的问题了。

  • exclude all phantom/weak/soft etc. references👉【排查泄漏首选】只保留强引用,屏蔽缓存类弱引用干扰。
  • include all references:全部引用都展示(会出来大量 WeakHashMap 等弱引用,信息很乱)。

实际排查时主要关注哪些对象?

如果是生产环境 Java 应用,我一般会重点关注这些:

类型重点检查
HashMap是否无限增长
ConcurrentHashMap是否存在无上限缓存
String数量是否异常
byte[]是否存在大量数据、文件、请求内容
Thread是否存在异常线程
ThreadLocal是否长期持有业务对象
Session是否保存了大量数据
ClassLoader是否存在重复部署导致无法释放
业务对象是否数量异常、长期存活

特别是看到:

Retained Heap 很大

不要马上判断是泄漏。

应该继续问:

谁引用它? 为什么引用? 这个对象正常情况下应该存在多久? 有没有清理机制?

一个简单的实际案例

假设客户反馈:

TongWeb 运行几天以后内存越来越高,最后 OOM。

我们可以按照下面的方式排查:

最终可能发现:

某个 static ConcurrentHashMap ↓ 不断 put 数据 ↓ 没有过期机制 ↓ 对象越来越多 ↓ Retained Heap 持续增长 ↓ Full GC 无法回收 ↓ 最终 OOM

这才是一次比较完整的内存问题排查。


还有一个非常实用的方法:对比多个 Heap Dump

如果问题是:

内存随着运行时间不断上涨

不要只生成一个 Heap Dump。

可以在不同时间分别生成:

dump-01.hprof dump-02.hprof dump-03.hprof

例如:

第一次:JVM 使用 3G 第二次:JVM 使用 5G 第三次:JVM 使用 7G

然后分别使用 MAT 分析。

重点比较:

哪些对象越来越多? 哪些对象 Retained Heap 不断增加? 哪些对象始终没有被释放?

这种方式往往比只分析一次 Heap Dump 更容易发现真正的内存泄漏。


小结一下

如果刚开始接触 MAT,不需要一次把所有功能都学会

先记住这几个:

Heap Dump ↓ Leak Suspects ↓ Histogram ↓ Dominator Tree ↓ Path to GC Roots

分别解决:

Heap Dump → 保存 JVM 某一时刻的内存现场 Leak Suspects → MAT 帮你找可疑点 Histogram → 看什么对象最多 Dominator Tree → 看谁占住了最多内存 Path to GC Roots → 看为什么这些对象一直没有被回收

最终目的不是“看懂 MAT 里的所有数据”,而是回答三个问题:

谁占用了内存?

为什么占这么多?

为什么 GC 没有把它回收?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 17:38:14

Clawdbot深度拆解:AI客服智能对话引擎与多渠道接入实战

2. Clawdbot 核心功能拆解 2.1 智能对话引擎:不止是聊天机器人 很多朋友一听到 AI 客服机器人,第一反应就是"不就是个自动回复吗"。说实话,Clawdbot 的智能对话引擎完全不是传统意义上的 FAQ 应答机,它在设计上做了几个…

作者头像 李华
网站建设 2026/9/8 17:38:02

WandEnhancer 三步解锁 WeMod Pro:本地补丁工具完整上手教程

WandEnhancer 三步解锁 WeMod Pro:本地补丁工具完整上手教程 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/GitHub_Trending/we/Wand-Enhancer 用 WeMod 免费版每天被倒计…

作者头像 李华
网站建设 2026/9/8 17:36:36

Java集合源码与数据结构:从ArrayList到HashMap的底层原理

ArrayList和LinkedList的区别是什么?HashMap的底层结构长什么样?HashSet为什么能保证元素不重复?这几个问题,几乎是Java面试必问的基础题,也是很多人在准备校招和社招时最先背的“八股文”。可一旦面试官追问到“Array…

作者头像 李华
网站建设 2026/9/8 17:35:33

IA-LUT:4D查找表破解暗光视频增强的实时与一致性难题

暗光视频增强在业内一直是个“做了很多年但落地很难”的方向。单帧图像增强的论文层出不穷,效果也确实越做越好,但一旦从图片切到视频,各种问题就冒出来了——最典型的就是实时性不够和帧间闪烁严重。我最早接触这个方向的时候,试…

作者头像 李华
网站建设 2026/9/8 17:34:28

大疆无人机对接指南:从SDK选型到实战踩坑全解析

“大疆无人机对接”这几个字,如果你不是圈内人,第一眼看到可能觉得不就是把飞机连上手机或遥控器么。但真做起来你会发现,这个“对接”二字涵盖的东西远比想象中复杂——它可能是指用Mobile SDK把航拍画面和飞行数据接进自家App,也…

作者头像 李华