用堆快照分析闭包内存泄漏需三步:先强制GC再拍基准快照,执行操作后再次GC并拍对比快照;在Comparison视图筛选(closure),关注#New为正且Retained Size大的条目;点击展开查看Scope捕获变量和Retainers引用链,结合多次快照验证是否稳定泄漏。

在浏览器中用堆快照分析闭包导致的内存泄漏,核心是“拍得准、比得清、追得深”。操作本身不复杂,但关键步骤容易跳过或误判。
一、先强制 GC,再拍快照
别一上来就点“Take heap snapshot”。必须先手动触发垃圾回收:
- 打开 Chrome DevTools → Memory 面板
- 点击左上角的 小垃圾箱图标(Collect garbage),等几秒直到控制台无输出、内存曲线平稳
- 再点击 Take heap snapshot 拍下第一张(Baseline)
- 执行疑似泄漏的操作(比如打开又关闭一个图表组件 3 次)
- 再次 GC → 再拍一张快照
二、用 Comparison 视图锁定增长的 Closure
单看一张快照没意义,要对比才能看出异常:
- 在快照列表中选中第二张 → 右上角下拉菜单切换为 Comparison
- 左侧参照选择第一张快照
- 在 Constructor 列筛选 (closure) —— 注意括号是英文,直接输 closure 就能过滤出来
- 重点关注 # New 列为正数、且 Retained Size 明显偏大的行
- 如果同一 Closure 名称反复出现新增实例(比如每次点按钮都多一个),基本就是泄漏源头
三、点开 Closure 查 Scope 和 Retainers
找到可疑 Closure 后,真正定位泄漏对象在这一步:
- 点击该行左侧三角展开,选中一个具体实例
- 右侧面板切到 Scope 标签:看它捕获了哪些变量。常见泄漏线索包括 hugeArray、chartInstance、document.getElementById('xxx') 等
- 再切到 Retainers 标签:看谁在“拽住”这个 Closure 不放。重点看顶部几层 —— 如果显示被 window、setInterval、EventListener 或某个全局缓存 Map 引用,说明生命周期失控
四、交叉验证是否真泄漏
避免把临时驻留当成泄漏:
- 重复同样操作 2–3 次,再拍第三张快照对比:如果 # New 持续递增,不是偶发而是稳定泄漏
- 回到 Scope 里找的那个大对象(比如一个 8MB 的数组),检查它是不是每次操作都新建但没销毁
- 如果 GC 后它还在,并且 Retainers 链没断,那它就是被强引用锁死的真实泄漏对象











