JVM 调优之 Dump 文件详解(Heap Dump + Thread Dump)
2026/6/23 8:11:19 网站建设 项目流程

JVM Dump 是故障定位、性能调优、内存泄漏、死锁分析的核心依据,主要分两大类:线程快照 (Thread Dump)堆快照 (Heap Dump),下面从概念、场景、生成、分析、实战逐一讲解。


一、基础概念区分

1. Thread Dump(线程转储 / 线程快照)

  • 定义:某一时刻 JVM 内所有线程的运行状态、调用栈、锁信息的文本快照。
  • 作用:排查死锁、线程阻塞、线程池耗尽、CPU 飙高、接口卡顿、死循环
  • 格式:纯文本,体积小、生成快,可多次连续抓取。

2. Heap Dump(堆转储 / 堆快照)

  • 定义:某一时刻 JVM整个堆内存(新生代、老年代、元空间除外)的对象实例、引用关系、对象大小、类信息的二进制文件。
  • 作用:排查内存泄漏、OOM、堆内存溢出、大对象、内存占用过高
  • 格式:二进制.hprof文件,体积和堆内存一致,大堆生成 / 分析较慢。

补充:还有GC Dump(GC 日志)、JFR 飞行日志,不属于传统 Dump,是辅助调优手段。


二、Thread Dump 线程快照(重点:线程问题排查)

1. 线程状态(核心识别点)

JVM 线程常见 6 种状态,Dump 中关键字对应:

  1. RUNNABLE:可运行 / 正在执行(CPU 繁忙、死循环多为此状态)
  2. BLOCKED被锁阻塞(等待 synchronized 锁,典型死锁场景)
  3. WAITING:无限等待(wait()/join(),主动休眠等待唤醒)
  4. TIMED_WAITING:限时等待(sleep()wait(time)、线程池空闲线程)
  5. TERMINATED:线程已结束
  6. NEW:线程未启动

2. 生成 Thread Dump 的 4 种常用方式

前提:先拿到Java 进程 PID

# 查Java进程PID jps -l # 或 ps -ef | grep java

方式 1:jstack(最常用,JDK 自带)

# 单次输出到控制台 jstack 进程PID # 输出到文件(推荐) jstack PID > thread_dump_$(date +%Y%m%d%H%M).log # 连续抓取3次(间隔2秒,排查瞬时卡顿/死循环) jstack PID > td1.log sleep 2 jstack PID > td2.log sleep 2 jstack PID > td3.log

方式 2:kill -3(Linux 原生,不杀进程)

kill -3 PID
  • 不会终止进程,线程栈直接输出到 JVM 标准错误流(Tomcat/Java 容器一般输出到catalina.out、nohup.out)。

方式 3:Arthas(线上首选,无侵入)

线上生产环境优先用 Arthas,无需重启:

# 进入arthas as # 查看所有线程栈 thread # 查看指定线程栈 thread 线程ID # 一键导出全量线程dump thread -all > /tmp/thread.log

方式 4:JVisualVM / JConsole(图形化,本地测试)

可视化工具直接点击「线程→线程 Dump」,适合开发环境。

3. 典型问题 & 解读案例

(1)死锁 Deadlock

Dump 末尾会明确提示Found 1 deadlock.,同时标注两个线程互相持有对方锁。现象:接口卡死、服务不响应、线程大量 BLOCKED。

(2)CPU 100%(线程死循环)

排查步骤:

  1. top -Hp PID找到占用 CPU 最高的线程 TID(十进制)
  2. 转十六进制:printf "%x\n" 十进制TID
  3. jstack PID搜索十六进制线程 ID,定位死循环代码行。

(3)线程池耗尽、任务堆积

大量线程处于WAITING,栈帧卡在线程池getTask(),说明任务提交速度 > 处理速度。


三、Heap Dump 堆快照(重点:内存泄漏、OOM)

1. 触发时机 & 应用场景

适用场景:

  • 应用抛出java.lang.OutOfMemoryError: Java heap space堆溢出
  • 内存持续上涨、Full GC 频繁、GC 后内存不释放(内存泄漏
  • 排查大对象、大集合、静态集合常驻内存

2. 生成 Heap Dump 的 5 种方式

方式 1:OOM 自动生成(生产必配JVM 参数)

发生 OOM 时自动 dump 堆,事后溯源最有效,无需人工干预。

# JDK8 常用配置 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/jvm/dump/heap_dump.hprof

参数说明:

  • +HeapDumpOnOutOfMemoryError:OOM 时自动生成堆快照
  • HeapDumpPath:指定 dump 文件路径(建议独立磁盘,避免占满分区)

注意:堆多大,文件就多大,大堆 (8G/16G) 生成会卡顿,短暂影响业务

方式 2:jmap(JDK 自带命令,手动抓取)

# 1. 导出整个堆(包含所有对象,完整分析,推荐) jmap -dump:format=b,file=/tmp/heap.hprof PID # 2. 只导出存活对象(忽略已死对象,文件更小) jmap -dump:live,format=b,file=/tmp/heap_live.hprof PID # 3. 查看堆概览(先看整体,不用分析大文件) jmap -heap PID

风险提醒

  • jmap会触发STW(Stop-The-World),堆越大、停顿越久。
  • 生产大堆(>4G)不建议频繁执行,优先用 Arthas / JFR。

方式 3:Arthas(线上低侵入抓取,推荐生产)

# 进入arthas后,导出堆快照 heapdump --live /tmp/heap.hprof
  • --live:只导出存活对象,体积更小、速度更快。

方式 4:JVisualVM / JConsole 图形化

本地测试、测试环境使用,界面点击「堆 Dump」即可。

方式 5:JVM 启动参数 -XX:+DumpHeapBeforeFullGC

每次 Full GC 前自动 dump,用于排查频繁 Full GC。

3. 关键 JVM 参数补充(Dump 相关)

# 限制dump文件大小、压缩等(可选) -XX:+HeapDumpCompressionLevel=1 # 压缩hprof,减小体积 -XX:HeapDumpTimeout=300 # dump超时时间

4. Heap Dump 核心分析工具

(1)MAT(Eclipse Memory Analyzer,行业标准

  • 开源、功能最强,专门分析.hprof
  • 核心功能:泄漏可疑报告、对象直方图、支配树、线程栈、引用链
  • 用法:打开 hprof 文件 → 选择Leak Suspects(泄漏疑点)一键分析。

(2)JVisualVM

JDK 自带,轻量,适合简单分析、本地调试。

(3)JProfiler

商业工具,可视化强,付费,企业常用。

(4)在线工具(小文件临时分析)

如 HeapHero,适合几 G 以内小堆快速查看。

5. 堆 Dump 核心分析思路(调优实战流程)

  1. 看直方图(Histogram)按类统计对象数量、占用内存,找出实例数异常多、单类占比极高的类。

  2. 查大对象 / 大集合定位ArrayList/HashMap等集合无限膨胀、未释放。

  3. 分析引用链(Reference Chain)找到「谁持有这个对象的引用」—— 内存泄漏本质:对象本该被 GC,却被强引用一直持有。 常见泄漏点:

    • 静态集合(static List)不断 add 不 clear
    • 线程池、ThreadLocal 未手动 remove
    • 数据库连接、IO 流、缓存未关闭 / 过期
    • 第三方框架内存泄漏
  4. 查看类加载 & 元空间区分是堆溢出还是元空间溢出(Metaspace OOM)


四、Thread Dump vs Heap Dump 选型(什么时候用哪个?)

现象优先使用典型问题
CPU 持续 100%、接口超时、卡死Thread Dump死循环、死锁、线程阻塞
OOM 报错、内存持续上涨、Full GC 频繁Heap Dump内存泄漏、大对象、堆溢出
服务间歇性卡顿、偶发超时两者结合线程阻塞 + 内存波动

五、线上生产最佳实践(避坑)

  1. 必配 OOM 自动 Dump 参数线上所有 Java 应用强制加上HeapDumpOnOutOfMemoryError,出问题才有溯源依据。
  2. Dump 文件单独挂载磁盘避免堆很大时,dump 文件占满系统盘导致服务宕机。
  3. 大堆慎用 jmap -dump8G+ 堆优先用 Arthas 抓取,减少 STW 停顿。
  4. 抓取策略
    • 线程问题:连续抓 2~3 份 Thread Dump(间隔 2s)对比状态。
    • 内存问题:GC 高峰期抓取 Heap Dump,优先加--live
  5. Dump 文件及时清理hprof 文件体积巨大,分析完立即删除。

六、常见问题答疑

  1. Dump 文件打不开 / 分析卡顿?
    • 增大 MAT/JVisualVM 的启动堆内存(修改mat.ini加大-Xmx)。
  2. 多次 Dump 内容不一样正常吗?正常,线程、对象状态是动态变化的。
  3. live 和不 live 区别?live只保留存活对象,文件小、分析快;不带 live 包含垃圾对象,适合完整复盘。
  4. STW 影响业务怎么办?低峰期抓取,或使用 JFR(Java Flight Recorder)替代,几乎无停顿。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询