线上java内存泄漏排查关键在于建立“现象→指标→快照→引用链→代码”闭环链;三个硬信号是:堆内存最低点持续抬高、老年代占用率长期>85%、full gc频次增但回收量少。

掌握线上 Java 内存泄漏排查,关键不是背原理,而是建立“现象→指标→快照→引用链→代码”的闭环判断链。原理要服务于动作,而不是反过来。
看准内存泄漏的三个硬信号
别一涨就 dump,先确认是不是真泄漏:
- 堆内存曲线平滑上扬,且每天最低点(比如凌晨 GC 后)持续抬高——说明有对象“沉底”没被回收;
- 老年代(Old Gen)占用率长期 >85%,Full GC 频次增加但每次回收量
- Young GC 频率不变,但每次 GC 后存活对象比例明显上升,说明更多对象在躲过 Minor GC 后直接晋升到老年代。
用对命令,三步锁定可疑进程和时段
不依赖图形化工具,靠终端快速收敛范围:
- jps -l 找出目标服务 PID;
-
jstat -gc -h10
5000 每 5 秒采样一次,观察 O(Old)、YGC、FGC、GCT 变化趋势,持续 2–3 分钟; - 发现老年代持续增长后,立即用 jcmd
VM.native_memory summary 和 jcmdGC.run_finalization 辅助排除 native 泄漏或 finalizer 堆积干扰。
导出 dump 要轻、准、可比
避免影响线上服务,也避免 dump 失真:
- 优先用 jcmd
VM.native_memory baseline + jcmdGC.run 清理浮点对象后再 dump; - 执行 jcmd
VM.native_memory summary 对比 baseline,确认无显著 native 增长; - 再用 jcmd
VM.native_memory summary_diff 查差异,若 native 稳定,才用 jcmdGC.heap_dump /tmp/heap_$(date +%s).hprof 导出; - 建议间隔 10–15 分钟采集两个 dump,用于 MAT 的 “Heap Dump Comparison”,直接定位增长对象类型。
用 MAT 快速聚焦泄漏根因
别陷入全量对象扫描,直奔关键视图:
- 打开 dump 后,先看 Overview → Top Consumers,找 Retained Heap 排名前三的类或实例;
- 右键该类 → Merge Shortest Paths to GC Roots → exclude weak/soft references,只保留强引用链;
- 重点检查路径中是否含 static、ThreadLocal、ClassLoader、Singleton、CacheManager、EventListener 等高风险节点;
- 用 OQL(Object Query Language) 快速验证:比如
SELECT * FROM java.lang.ThreadLocal WHERE @retainedHeap > 1000000,查大 ThreadLocal 实例。
整个过程不复杂,但容易忽略节奏和取舍——先信监控曲线,再信 GC 日志,最后才信 dump。原理藏在每一步命令的输出含义里,而不是书本定义中。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











