在 performance 面板中观测闭包内存泄漏,需先清理环境、规范操作节奏并触发 gc;重点观察 js heap 是否阶梯式上升,结合 allocation sampling 定位高频 closure 及其 retained size,再用 memory 快照验证 retainers 路径。

在 Performance 面板中观测闭包引起的内存泄漏,核心是看 JS Heap 曲线是否呈现阶梯式上升,并结合火焰图与分配采样定位闭包关联的异常内存驻留。
打开 Performance 面板前先做三件事
- 关掉所有无关标签页和浏览器扩展(尤其 Vue/React DevTools、广告拦截器)
- 确保只保留待测页面,避免干扰数据
- 清空缓存与历史记录(Ctrl+Shift+Del → 仅勾选“缓存的图像和文件”)
录制时按节奏操作,让 GC 有机会工作
- 执行完整操作闭环:比如“打开弹窗 → 等待2秒 → 关闭弹窗 → 等待3秒”,重复至少3轮
- 每轮结束后手动点击 Memory 面板的垃圾桶图标触发垃圾回收(GC),再继续下一轮
- 录制总时长控制在 25–35 秒,太短看不出趋势,太长会模糊关键节点
重点观察 JS Heap 轨道的走势
- 如果每次关闭弹窗后内存都回落到接近起点(±1MB 内),基本无泄漏
- 若第三轮操作结束时 JS Heap 比第一轮同位置高出 5MB 以上,且曲线呈明显阶梯状抬升,说明有对象未释放
- 注意对比 Nodes 和 Listeners 数量轨道:若它们同步增长,大概率是事件监听 + 闭包共同锁住了 DOM 或大数组
用 Allocation Sampling 定位闭包源头
- 开始录制前,在右上角齿轮中勾选 Allocation sampling
- 录制完成后,切换到底部 Summary 标签 → Bottom-Up 视图 → 按 Allocations 列降序排列
- 找出高频分配的 Closure 类型(如
(closure) handleScroll或(closure) fetchData),点开对应堆栈,看它是否在循环或组件初始化中被反复创建 - 若某闭包的 Self Size 很小但 Retained Size 超过 200KB,说明它捕获了不该持有的大对象(如整个
document.getElementById('app')或万级数组)
交叉验证:配合 Memory 面板快照确认
- 在 Performance 录制中找到内存峰值时间点,暂停并记下毫秒数
- 切换到 Memory 面板,拍一张快照,筛选 Constructor 为 Closure,按 Retained Size 排序
- 点击可疑闭包 → 查看右侧 Retainers → 若显示
window → timer → closure或EventListener → closure → Array,就坐实了闭包长期持有了不该留的对象
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











