Chrome DevTools堆快照对比定位内存泄漏:先拍GC后的基准快照(Baseline),再执行完整操作闭环、GC后拍第二张,切换Comparison模式,聚焦#New>0且Size Delta>0的Constructor,顺Retaining Path查全局变量、未清定时器、未解绑监听器或detached DOM等强引用源。

直接用 Chrome DevTools 的堆快照对比(Comparison)视图,是发现新增泄漏对象最高效的方式:先拍操作前的基准快照,再执行操作并手动触发垃圾回收后拍第二张,切换 Comparison 模式,聚焦 # New > 0 且 Size Delta > 0 的构造函数,再顺 Retaining Path 查谁在“拽着”它不放。
怎么拍两张靠谱的快照
拍得不准,对比就全偏了。关键不是“点两次录制”,而是控制状态:
- 第一张(Before):页面加载完成、无动画、无定时器运行、无 pending 请求,先点左上角垃圾桶图标手动 GC,再立即拍下,命名为 “Baseline”
- 第二张(After):执行一次完整操作闭环(比如打开模态框 → 填写 → 提交 → 关闭),等几秒让 JS 稳定下来,再点垃圾桶手动 GC,立刻拍下
- 避免干扰:关闭其他标签页、禁用浏览器扩展,最好用隐身窗口测试
在 Comparison 视图里盯什么
选中 After 快照 → 顶部下拉选 “Comparison” → 对比目标选 Before。此时表格只显示变化项,重点看三列:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- # New:After 中新增的该类实例数(Before 里已销毁的不算)
- Size Delta:内存净增长量(单位字节),正数说明不仅数量涨,还“变胖”了
- Constructor:构造函数名——优先排序查看 # New 和 Size Delta 都明显上升 的行,比如 MyModal、ChartRenderer、(closure)、Array
点开后怎么看清根源
找到可疑构造函数,点击左侧三角展开,看具体实例。鼠标悬停任一实例,右侧自动显示 Retaining Path(保留路径):
立即学习“Java免费学习笔记(深入)”;
- 路径以 window 或 globalThis 开头 → 检查是否意外赋值给全局变量(如漏写
var/let) - 路径含 setTimeout / setInterval → 回调闭包可能捕获了组件实例或大数据,未 clearTimeout/clearInterval
- 路径经过 EventListener → 绑定监听器后没调
removeEventListener,尤其注意匿名函数/箭头函数无法解绑 - 路径指向已移除的 DOM 节点(如
detached HTMLDivElement)→ JS 变量仍持有该节点或其 parentNode/ownerDocument
怎么确认真是泄漏,不是临时抖动
单次对比容易受 GC 时机影响,需交叉验证:
- 重复“操作 → GC → 快照”流程,生成 Snapshot 1、2、3、4
- 依次做
2−1、3−2、4−3对比,观察同一构造函数的 # New 是否稳定递增(如每次多出 1 个 MyComponent) - 若增长趋势线性持续,基本可判定泄漏;修复后重测,该值应回归稳定或归零

















