直接对比操作前后的堆快照可快速定位内存泄漏点:先拍基线快照,再执行可疑操作并拍第二张,通过comparison视图查看delta为正的对象,重点关注detached dom trees、持续增加的组件实例及retainers引用链,结合class filter筛选和performance面板验证。

直接看堆快照里的“增长对象”和“谁在留着它”,就能快速定位泄漏点。关键不是拍一张图,而是对比操作前后的变化,再顺藤摸瓜找引用链。
拍两次快照做对比
先在页面空闲、刚加载完时拍一个基线快照(Snapshot 1);再执行你怀疑的操作(比如打开又关闭弹窗、切换路由),等几秒让垃圾回收跑完,再拍第二个快照(Snapshot 2)。在 Snapshot 1 的下拉菜单里选 “Comparison”,然后选 Snapshot 2 —— 这时列表会显示哪些对象是新增的、哪些没被释放。
- 重点关注 # Delta 列为正数且数值较大的类型,比如
HTMLDivElement、EventListener、自定义类实例 - 特别留意 Detached DOM trees:这类节点已从文档中移除,却还被 JS 引用着,是泄漏高发区
- 如果某构造函数(如
MyComponent)的实例数每次操作后都+1,基本就是组件没销毁干净
查 Retainers 追溯源引用
在对比视图里点开一个可疑对象(比如一个 Detached 的 div 或一个监听器),右侧会显示它的 Retainers(持有者)面板。这里列出所有直接或间接引用它的对象,按引用链从近到远排列。
- 顺着引用链往上翻,重点看是不是有闭包、全局变量、定时器、未清理的事件监听器在“拽着”它
- 常见线索:
Closure下挂着大数组或 DOM 节点、window上挂了临时缓存、setInterval回调里用了外部变量 - 如果看到
DOMWindow→Closure→HTMLDivElement,大概率是某个事件回调没解绑,导致整个 DOM 树无法释放
过滤和搜索缩小范围
快照对象太多时,别手动翻页。用右上角的 Class filter 输入关键词快速筛选:
-
Detached:直接定位分离 DOM 节点 -
EventListener或function:查未移除的监听器 - 你的组件名或类名(如
Modal、ChartView):确认实例是否堆积 -
Array或Object配合 Retained Size 排序:找占用内存大的“嫌疑对象”
结合其他面板交叉验证
单靠快照有时不够直观,建议同步打开其他视图辅助判断:
- 在 Performance 面板开启内存录制,看 JS 堆大小曲线是否持续爬升、GC 后不回落
- 用 Allocation instrumentation on timeline 记录操作过程,观察哪段代码频繁分配大对象且不释放
- 控制台运行
getEventListeners(document)或getEventListeners(window),手动检查高频事件监听是否越积越多
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











