Skip to content

浏览器内存泄漏如何排查

排查浏览器内存泄漏通常分为 “发现异常”“定位代码”“修复验证” 三个阶段。


第一阶段:发现异常

在深入分析之前,首先要确认是否真的存在内存泄漏。

1. 观察 Performance (性能) 面板

  • 操作: 打开 DevTools (F12Ctrl+Shift+I) -> 切换到 Performance 面板。
  • 设置: 勾选 Memory 复选框。
  • 录制: 点击录制按钮(实心圆),然后在页面上进行操作(例如:打开弹窗再关闭、切换路由、滚动列表)。操作完后停止录制。
  • 分析: 观察 JS Heap (JS 堆) 曲线。
    • 正常: 曲线呈锯齿状(上升后下降,说明垃圾回收 GC 正常工作)。
    • 泄漏: 曲线呈阶梯状(只升不降,或者下降幅度很小,说明内存没有被释放)。

第二阶段:定位代码

确认有泄漏后,使用 Memory 面板找出具体的泄漏对象。

快照对比法,适用于查找全局变量闭包被遗忘的 DOM 引用

  1. 打开 Memory 面板,选择 Heap snapshot
  2. 步骤一: 点击 Take snapshot(拍摄初始快照)。
  3. 步骤二: 进行可能导致泄漏的操作(例如:打开组件 A,然后关闭组件 A)。
  4. 步骤三: 再次点击 Take snapshot。
  5. 对比:
    • 在左侧列表中选择第二个快照。
    • 在视图下拉菜单中选择 Comparison(对比)。
    • 关键指标: 查看 # New 列。如果组件 A 关闭后,仍然有大量的 Constructor(如 VueComponent, ReactComponent, 或自定义类)显示在 # New 中,说明这些对象没有被销毁。
    • 查看引用链: 点击该对象,在下方的 Retainers(保留树)面板中查看。这能告诉你是谁“抓着”这个对象不让它被回收(通常是一个全局数组、定时器或 DOM 元素)。

第三阶段:常见泄漏原因与验证

检查以下常见问题:

  1. 意外的全局变量
  2. 被遗忘的定时器
  3. 闭包
  4. 脱离 DOM 的引用:DOM 节点已经从页面移除了,但 JS 变量还拿着它的引用
  5. 事件监听未移除