JVM 内存泄漏排查中支配树(Dominator Tree)怎么看

秋雪大大_9465

秋雪大大_9465

2026-10-17

464人浏览

原创

支配树用于精准定位内存泄漏根因:默认按retained heap降序排列,优先分析前3–5项中业务包名类节点;右键查path to gc roots(排除弱/软/虚引用)获取强引用链;结合dominator depth≤3且retained heap>100mb、实例数突增及首个业务类位置交叉验证。

jvm 内存泄漏排查中支配树(dominator tree)怎么看

支配树不是用来“通读”的,而是用来“狙击”的——盯住Retained Heap最大的几个节点,逆向查强引用链,再结合业务逻辑确认是否真泄漏。

看排序:Retained Heap降序是核心线索

打开MAT的Dominator Tree视图,默认按“Retained Heap”从大到小排列。这个值代表:如果该对象被回收,整个子树(所有被它支配的对象)都会被释放,对应的真实内存大小。

  • 排第一的不一定是泄漏源,但它是当前堆中“内存控制力最强”的节点——比如一个静态缓存Map、Spring的ApplicationContext、或某个未清理的ThreadLocalMap
  • 重点关注前3–5项,尤其是业务包名开头的类(如com.yourcompany.cache.UserSessionCache),而非java.util.HashMap或byte[]这类底层容器
  • 若看到大量相同数组(如char[]、byte[])扎堆,别点进去;先右键→“Immediate Dominators”,看是谁在统一持有它们

看路径:Path to GC Roots只留强引用

在支配树中选中可疑节点,右键→“Path to GC Roots” → 勾选“exclude weak/soft/phantom references”。这一步过滤掉所有不影响GC的引用,只保留真正阻止回收的强引用链。

  • 典型泄漏路径包括:ThreadLocalMap → ThreadLocal → 业务对象 → 大数组,或StaticCache → HashMap → Key → Value → List → 元素对象
  • 路径中若出现java.lang.Thread.threadLocals,且线程来自线程池(如pool-1-thread-3),要高度警惕ThreadLocal泄漏
  • 路径过长时,可点击中间某层对象(如某个Service实例),再对它单独查支配树——真正的根因常藏在第二层

看深度与上下文:Dominator Depth + 时间线交叉验证

MAT中右键节点→“Show in Overview”,查看“Dominator Depth”。深度≤3且Retained Heap > 100MB的节点,优先级最高。

  • 深度小 = 距离GC Roots近 = 控制范围广,更可能是源头
  • 单靠快照不够,要对比两次jmap -histo输出:若某类实例数1小时内涨了4倍,又恰好落在高Retained Heap节点下方,可信度大幅提升
  • 顺着支配路径往上找,第一个出现的业务包名类(如com.yourcompany.order.OrderProcessor),基本就是泄漏代码所在位置,重点检查它的静态字段、单例缓存、监听器注册、回调未注销等模式

防误判:识别常见干扰项

框架类和基础结构本身合法,但容易成为“中转站”,不能见Retained Heap大就认定是泄漏。

  • 排除java.*、sun.*、javax.*下的原生类(除非你改了JVM)
  • Spring的GenericApplicationContext、Tomcat的WebappClassLoader、线程池ThreadPoolExecutor本身长期存活,需进一步查它里面是否堆积了不该存在的业务对象
  • 注意[Synthetic]标记的虚拟节点——它可能代表整个线程栈或ClassLoader,真实泄漏源往往藏在它展开后的子节点里

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

2026.10.16

0

10

OpenJDK怎么配置Java开发环境
OpenJDK怎么配置Java开发环境

怎样用OpenJDK搭建开发环境?本专题介绍版本选择、下载安装、环境变量配置和编译运行验证,帮助你理清JDK的作用及基本配置流程,并通过简单程序检查环境是否可用,为后续项目开发做好准备。

2026.10.16

0

10

OpenJDK怎么部署Java应用
OpenJDK怎么部署Java应用

Java项目开发完成后,怎样部署到目标环境并正常运行?本专题介绍OpenJDK应用部署流程,涵盖运行环境准备、版本兼容检查、应用打包、启动参数配置和日志查看,帮助你理清部署前后的操作顺序,减少环境差异造成的运行问题。

2026.10.16

0

10

Revel框架模板渲染与表单验证
Revel框架模板渲染与表单验证

本专题围绕Revel框架视图层开发,介绍模板语法、变量输出、布局复用、表单提交、参数绑定与验证规则,帮助开发者完成安全规范的页面交互。

2026.10.16

0

15

Revel框架MVC路由与控制器
Revel框架MVC路由与控制器

本专题聚焦Revel框架MVC核心机制,讲解路由定义、控制器Action、参数绑定、请求响应和反向路由,并结合常见场景梳理接口请求处理流程。

2026.10.16

0

15

Revel框架入门与安装配置
Revel框架入门与安装配置

本专题从Revel框架环境搭建讲起,系统介绍命令行工具安装、项目创建、目录结构、配置文件及热代码重载,帮助开发者快速完成首个Go Web应用。

2026.10.16

0

15

Linux 新手先学哪些命令
Linux 新手先学哪些命令

Linux新手命令专题汇集终端基础、文件目录操作、文本查看、软件安装和权限管理等入门文章,帮助按实际任务练习常用命令并建立命令行操作习惯。

2026.10.15

0

20

MySQL 忘记密码怎么办
MySQL 忘记密码怎么办

MySQL忘记密码专题汇集不同版本与系统下的root密码重置方法,覆盖MySQL 5.7、8.0、Mac、Linux及本地集成环境,并提示恢复权限与重新登录的检查步骤。

2026.10.15

0

18

Vue.js 中 ref 和 reactive 的区别
Vue.js 中 ref 和 reactive 的区别

Vue.js中ref和reactive的区别专题汇集两种响应式API的定义、访问方式、对象解构、侦听与性能取舍等文章,帮助结合实际状态类型选择合适写法。

2026.10.15

0

20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习