Appearance
浏览器内存泄漏如何排查
排查浏览器内存泄漏通常分为 “发现异常”、“定位代码” 和 “修复验证” 三个阶段。
第一阶段:发现异常
在深入分析之前,首先要确认是否真的存在内存泄漏。
1. 观察 Performance (性能) 面板
- 操作: 打开 DevTools (
F12或Ctrl+Shift+I) -> 切换到Performance面板。 - 设置: 勾选
Memory复选框。 - 录制: 点击录制按钮(实心圆),然后在页面上进行操作(例如:打开弹窗再关闭、切换路由、滚动列表)。操作完后停止录制。
- 分析: 观察 JS Heap (JS 堆) 曲线。
- 正常: 曲线呈锯齿状(上升后下降,说明垃圾回收 GC 正常工作)。
- 泄漏: 曲线呈阶梯状(只升不降,或者下降幅度很小,说明内存没有被释放)。
第二阶段:定位代码
确认有泄漏后,使用 Memory 面板找出具体的泄漏对象。
快照对比法,适用于查找全局变量、闭包或被遗忘的 DOM 引用。
- 打开
Memory面板,选择 Heap snapshot。 - 步骤一: 点击 Take snapshot(拍摄初始快照)。
- 步骤二: 进行可能导致泄漏的操作(例如:打开组件 A,然后关闭组件 A)。
- 步骤三: 再次点击 Take snapshot。
- 对比:
- 在左侧列表中选择第二个快照。
- 在视图下拉菜单中选择 Comparison(对比)。
- 关键指标: 查看
# New列。如果组件 A 关闭后,仍然有大量的Constructor(如VueComponent,ReactComponent, 或自定义类)显示在# New中,说明这些对象没有被销毁。 - 查看引用链: 点击该对象,在下方的
Retainers(保留树)面板中查看。这能告诉你是谁“抓着”这个对象不让它被回收(通常是一个全局数组、定时器或 DOM 元素)。
第三阶段:常见泄漏原因与验证
检查以下常见问题:
- 意外的全局变量
- 被遗忘的定时器
- 闭包
- 脱离 DOM 的引用:DOM 节点已经从页面移除了,但 JS 变量还拿着它的引用
- 事件监听未移除