MAT 与 JProfiler 使用指南

MAT(Memory Analyzer Tool)和 JProfiler 是 Java 内存分析的两大利器。MAT 适合分析堆转储文件,JProfiler 适合实时监控和诊断。

掌握这两个工具,是排查内存问题的必备技能。

MAT(Memory Analyzer Tool)

MAT 是 Eclipse 提供的开源堆转储分析工具,适合分析大型堆转储文件。

安装与启动

# 下载地址
# https://www.eclipse.org/mat/downloads.php

# 启动 MAT
./MemoryAnalyzer

# 或命令行分析
./ParseHeapDump.sh /path/to/heap.hprof org.eclipse.mat.api:suspects

核心视图

1. Leak Suspects

自动分析可能的内存泄漏点:

// MAT 自动生成的报告
Problem Suspect 1:
The class "java.util.HashMap", 
which is loaded by "<system class loader>", 
occupies 2,147,483,648 bytes (50.00%) 
of java heap memory.

The class "java.util.HashMap$Node", 
which is loaded by "<system class loader>", 
occupies 1,073,741,824 bytes (25.00%) 
of java heap memory.

Keywords:
java.util.HashMap
java.util.HashMap$Node

2. Component Report

按组件分析内存占用:

// Component Report 示例
Component                        | Retained Heap | Percentage
-----------------------------------------------------------------
java.util.HashMap               |     2.5 GB    |    50.0%
  java.util.HashMap$Node[]      |     2.0 GB    |    40.0%
  java.lang.String               |     0.5 GB    |    10.0%
-----------------------------------------------------------------
com.example.service.Cache        |     1.0 GB    |    20.0%
-----------------------------------------------------------------
Thread stacks (local vars)      |     0.5 GB    |    10.0%

3. Histogram

对象直方图:

# 操作步骤
1. 点击 "Open Java Basics" -> "Histogram"
2. 可以按类名、包名过滤
3. 排序查看内存占用最大的类型
4. 右键 "Retained Heap" 查看详情

4. Dominator Tree

支配树视图:

# 支配树特点
1. 显示对象的支配关系
2. 可以快速找到内存占用最大的对象
3. 点击对象可以查看其引用链

常用查询

查找某类的所有实例

# 在 Histogram 中
1. 输入类名过滤
2. 右键 "List Objects" -> "with outgoing references"
3. 可以查看该类所有实例及其引用关系

查找 GC Roots 路径

# 在对象上右键
1. "Path to GC Roots" -> "exclude weak/soft references"
2. 显示到 GC Roots 的完整路径
3. 这是理解对象为何无法被回收的关键

OQL 查询

MAT 支持对象查询语言(OQL):

-- 查找所有包含特定字符串的 String 对象
SELECT s.toString() 
FROM java.lang.String s 
WHERE s.toString().contains("example")

-- 查找大于 1MB 的数组
SELECT p 
FROM byte[] p 
WHERE p.@length > 1048576

-- 查找特定包下的所有对象
SELECT * 
FROM com.example.* 
WHERE objectCount > 100

JProfiler

JProfiler 是商业性能分析工具,支持实时监控、CPU 分析、内存分析等功能。

安装与启动

# 下载地址
# https://www.ej-technologies.com/products/jprofiler/overview.html

# 启动 JProfiler
./jprofiler

# 或命令行快速启动
jprofilerui -sessionid=<session_id>

核心视图

1. Memory Views(内存视图)

# 内存视图功能
1. 实时显示堆内存使用
2. 显示各类对象的内存占用
3. 支持记录内存分配
4. 可以触发 GC 并对比

2. Heap Walker

堆分析器,类似 MAT:

# Heap Walker 功能
1. Classes:查看各类对象
2. Allocations:查看对象分配栈
3. References:查看对象引用
4. OQL:对象查询
5. GC Roots:查看 GC Roots

3. Allocation View(分配视图)

# 分配视图功能
1. 查看对象分配的位置
2. 记录分配栈
3. 分析热点对象
4. 找出分配最多的代码位置

实时监控

# 启动时附加到 JVM
java -agentpath:/path/to/jprofiler/bin/agen \
    -XX:+UseG1GC \
    -jar application.jar

# 或通过 JMX 连接
jprofilerui -> Session -> New Session -> JVM attach

常见分析场景

场景一:查找内存泄漏

# 步骤
1. 记录初始堆状态
2. 执行操作
3. 触发 GC
4. 对比堆变化
5. 查看增长最大的对象类型
6. 使用 Allocation View 查找分配位置

场景二:分析对象引用

# 步骤
1. Heap Walker 中找到对象
2. 使用 References 视图
3. 查看 incoming references(谁引用了我)
4. 查看 outgoing references(我引用了谁)
5. 追踪 GC Roots 路径

场景三:分析内存分配热点

# 步骤
1. 启用 Allocation Recording
2. 执行代码
3. 停止录制
4. 查看 "Call Tree" 视图
5. 找出分配最多的方法

VisualVM

VisualVM 是 JDK 自带的免费监控工具:

# 启动 VisualVM
jvisualvm

# 功能
1. 监控 CPU、内存、线程
2. 生成和查看堆转储
3. 采样分析 CPU
4. 插件扩展

Arthas 内存分析

Arthas 是阿里巴巴开源的 Java 诊断工具:

# 启动 Arthas
java -jar arthas-boot.jar

# 常用命令
dashboard                    # 查看概览
memory                      # 查看内存详情
heapdump /tmp/heap.hprof   # 导出堆转储
sc -d com.example.MyClass # 查看类详情

Arthas 与 MAT 配合

# 1. 使用 Arthas 获取堆转储(无需 OOM)
heapdump --live /tmp/heap.hprof

# 2. 使用 MAT 分析
./mat/MemoryAnalyzer /tmp/heap.hprof

工具对比

特性MATJProfilerVisualVMArthas
费用免费商业免费免费
实时监控部分
堆转储分析
CPU 分析
线程分析
适用场景OOM 分析性能调优快速诊断生产环境

选择建议

  • OOM 问题排查:首选 MAT
  • 性能调优:首选 JProfiler
  • 快速诊断:VisualVM 或 Arthas
  • 生产环境:Arthas(无需停机)