Skip to content

前端内存泄漏排查指南

更新: 5/4/2026 字数: 0 字 时长: 0 分钟

页面越用越卡、最终崩溃,典型的内存泄漏表现。下面是一套从定位 → 分析 → 修复的完整排查路径。

一、先确认是不是内存问题

打开 Chrome DevTools → Performance Monitor(或 Task Manager: Shift+Esc),观察:

  • JS heap size 是否随操作持续增长且不回落
  • DOM Nodes 数量是否只增不减
  • Listeners 数量是否异常增长

如果三者都随时间单调上升,基本可以确定是内存泄漏。

二、定位泄漏点:Memory 面板三板斧

1. Heap Snapshot(堆快照对比法)——最常用

核心思路:执行可疑操作前后分别打快照,对比新增对象。

操作步骤:

  1. 进入可疑页面,先点 Collect garbage(垃圾桶图标)强制 GC
  2. 打第一个 Snapshot(基线)
  3. 重复执行可疑操作 N 次(如反复打开/关闭弹窗、切换路由)
  4. 再次 GC,打第二个 Snapshot
  5. 切换到 Comparison 视图,按 # Delta 排序
  6. 重点看 Detached 开头的对象(脱离 DOM 但仍被引用的节点)

2. Allocation instrumentation on timeline(时间轴分配)

录制一段用户操作,查看内存分配的时间分布。蓝色竖条在录制结束后仍存在,就是未被回收的对象,点击可直接看到分配调用栈。

3. Allocation sampling(低开销采样)

适合长时间录制,开销小,能看出哪些函数在疯狂分配内存。

三、前端内存泄漏的五大常见元凶

类型典型代码修复方式
未解绑事件监听window.addEventListener 组件卸载未 removereturn () => removeEventListener(...)
定时器未清理setInterval / setTimeout 闭包持续持有组件引用clearInterval on unmount
闭包意外引用回调捕获大对象,生命周期长于对象解除引用 bigObj = null
游离 DOM删除 DOM 前已被 JS 变量/数组持有先解引用再 remove
全局缓存无上限window.cache[key] = ... 无淘汰策略改用 WeakMap 或 LRU

框架特有:

  • ReactuseEffect 忘记返回 cleanup;闭包捕获旧 state;Context 传递大对象
  • Vue$on / EventBus 未 $offwatch 未停止
  • 第三方库:ECharts / Leaflet / Monaco 未调用 dispose();WebSocket 未 close()

四、线上排查(无法开 DevTools 场景)

  1. performance.memory API(Chrome):采集 usedJSHeapSize 上报监控,画出趋势图定位爆发时间点
  2. 灰度 + 复现路径还原:结合用户操作路径(埋点)在本地复现
  3. Sentry / 字节内部的 Slardar 等 APM:订阅 OOM / 白屏事件,关联用户会话回放

五、快速自检 Checklist

js
// 常见修复模板 - React
useEffect(() => {
  const handler = () => { /* ... */ };
  window.addEventListener('resize', handler);
  const timer = setInterval(fn, 1000);
  const ws = new WebSocket(url);

  return () => {
    window.removeEventListener('resize', handler);
    clearInterval(timer);
    ws.close();
  };
}, []);

// 大对象缓存
const cache = new WeakMap();  // key 被回收时自动清理

六、推荐排查顺序

  1. Performance Monitor 看三条曲线确认泄漏存在
  2. Heap Snapshot 对比 → 找到新增最多的 Detached 对象 / 闭包
  3. 点进 Retainers(保留链)→ 找到谁还在引用它
  4. 顺着引用链回到源码 → 定位未清理的监听/定时器/缓存
  5. 修复后重复第 2 步验证曲线回落

需要我针对你页面用的框架(React / Vue)给更具体的代码审查清单,或帮你看某段具体代码是否有泄漏风险吗?