Java 内存泄漏分析与解决:MAT 工具指南

1. MAT 工具简介

MAT(Memory Analyzer Tool)是 Eclipse 基金会开发的 Java 堆转储分析工具,用于检测内存泄漏和优化内存使用。它能:

  • 解析 .hprof 堆转储文件
  • 可视化对象引用关系
  • 识别内存占用最高的对象
  • 定位未释放的引用链

2. 内存泄漏常见原因
类型 案例
静态集合 静态 HashMap 持续添加对象
未关闭资源 未调用 close()InputStream
监听器未注销 事件监听器未移除
内部类引用 非静态内部类持有外部类引用

3. MAT 使用步骤

步骤 1:生成堆转储

# 通过 jmap 命令生成堆转储文件
jmap -dump:format=b,file=heapdump.hprof <pid>

步骤 2:MAT 分析

  1. 打开 MAT,加载 heapdump.hprof
  2. 查看 Histogram(对象数量统计)
  3. 使用 Dominator Tree(内存支配树)定位大对象
  4. 通过 Path to GC Roots 追踪引用链

步骤 3:诊断泄漏点

  • 关注 Shallow Heap(对象自身内存)与 Retained Heap(关联对象总内存)
  • 检查 java.lang.ClassLoader 或自定义类的高内存占用

4. 内存泄漏示例与修复

泄漏代码

public class LeakExample {
    private static final Map<String, Object> cache = new HashMap<>(); // 静态集合
    
    public void addToCache(String key, Object value) {
        cache.put(key, value); // 对象永不释放
    }
}

MAT 分析结果

  • Histogram 显示 HashMap$Node 对象数量异常增长
  • Dominator Tree 指出 cache 占 80% 内存

修复方案

public class FixedExample {
    private static final WeakHashMap<String, Object> cache = new WeakHashMap<>(); // 弱引用
    
    public void addToCache(String key, Object value) {
        cache.put(key, new WeakReference<>(value)); // 允许 GC 回收
    }
}


5. 进阶技巧
  • 对比堆转储:在内存增长前后分别抓取堆转储,用 MAT 比较差异
  • OQL 查询:使用类 SQL 语法定位对象
    SELECT * FROM java.lang.String WHERE value.toString().startsWith("ERROR")
    

  • 排查线程:检查 Thread Local 变量的生命周期

最佳实践:结合 -XX:+HeapDumpOnOutOfMemoryError JVM 参数,在 OOM 时自动生成堆转储。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐