内存泄漏定位需三步对比、一层引用链、一个清理动作:先用Performance面板观察内存曲线趋势,再拍三张快照对比新增对象与Detached节点,最后沿Retainers向上追溯至window变量、未清除定时器或未销毁的监听器等源头。

定位内存泄漏不是靠“一眼看出”,而是靠三步对比、一层引用链、一个清理动作——关键不在拍多少张快照,而在拍得准、比得清、追得深。
先确认泄漏是否存在
别急着打开 Memory 面板。先用 Performance 面板做趋势判断:
- 打开 Performance 面板 → 勾选 Memory 选项 → 点击录制
- 在页面上重复执行疑似引发泄漏的操作(比如打开/关闭弹窗 5 次、切换路由 3 次)
- 停止录制后,看内存曲线:如果每次操作后内存都明显上升,且没有随空闲时间回落,就存在泄漏嫌疑
- 特别注意曲线末端是否持续爬升,而非锯齿状波动——后者可能是正常渲染开销
拍三张关键快照并对比
Memory 面板不自动报警,泄漏要靠人工对比才能坐实:
- Baseline 快照:页面完全空闲时,先点左上角垃圾桶图标手动触发 GC,再拍第一张
- 操作后快照:执行目标动作(如加载列表),再主动清理(移除监听器、调用 dispose()、置空引用),GC 后立刻拍第二张
- 重复后快照(可选):重复上述流程 2–3 次后再拍一张,观察增长是否阶梯式累积
- 选中最后一张快照 → 切换为 Comparison 模式 → 与 Baseline 对比
重点关注三类信号:红色 + 号行(新增对象)、Retained Size 不降反升(如某实例始终占 4MB)、Detached 开头的 DOM 类型(如 Detached HTMLDivElement)。
顺着 Retainers 追到真正源头
看到可疑对象(比如大量 (closure) 或 Detached 节点),别停在表面。右键点击 → “Reveal in Summary view”,再点开它右侧的 Retainers 标签:
- 勾选 Settings(齿轮图标)→ Show all objects,避免遗漏潜在持有者
- 从下往上读引用链:最底下是目标对象,往上是直接持有者,再往上是它的持有者……直到顶层
- 终点常见于:window.xxx(全局变量未清理)、setInterval(定时器没清除)、EventListener(DOM 已卸载但监听器还在)、第三方库实例(如 Chart、Editor 没调 .destroy())
- 若路径中出现 bound listener 或 debounced 函数名(如 onResize、searchHandler),基本就是未解绑或未取消的闭包
结合典型模式快速验证
快照异常往往对应几类高频问题,可交叉印证:
- DOM 残留:Detached 节点被 Map 缓存或闭包持有 → 查 React/Vue 卸载逻辑、document.createElement 后是否漏 remove()
- 定时器失控:Retainers 终点是 Timer → 检查 setTimeout/setInterval 是否配对 clear
- 缓存膨胀:Retained Size 大的 Object 或 Map → 查 Map.set() 后是否漏 delete(),优先改用 WeakMap
- 闭包捕获大对象:点开 (closure) → 展开 Properties → 找 [[Scopes]] → 看 data、config、ref 等变量是否本该释放却还挂着
不复杂但容易忽略











