DevTools Memory 面板

Memory 面板用于观察堆内存、堆快照、分配趋势和未释放引用,是排查内存泄漏的重要入口。

#type / concept #status / growing #tech / dev / frontend #platform / browser #resource / chrome-devtools

[!info] related notes

DevTools Memory 面板

一句话定义

Memory 面板是 Chrome DevTools 中用于拍摄堆快照、分析内存分配趋势、定位未被回收对象的内存分析工具。

核心机制 / 工作原理

它最适合回答什么问题

  • 当前页面的堆内存是否持续增长
  • 哪类对象占用最大
  • 哪些对象被谁持有,为什么没被回收
  • 是否存在 Detached DOM、闭包引用、监听器未释放等问题

三种快照类型

类型原理适用场景
Heap Snapshot拍摄当前堆内存的完整快照分析当前内存中有哪些对象、谁引用谁
Allocation instrumentation on timeline记录一段时间内的内存分配观察内存增长趋势,定位分配热点
Allocation sampling采样分配调用栈性能开销低,适合生产环境长时间采集

使用流程

1. 拍摄基线快照

  • 打开 DevTools → Memory 面板
  • 选择 “Heap snapshot” → 点击 “Take snapshot”
  • 记录初始状态

2. 执行可疑操作

  • 页面切换、组件挂载卸载、重复打开关闭弹窗等

3. 拍摄第二份快照

  • 操作后再拍一份 Heap snapshot

4. 比较快照

  • 选择第二份快照,在 Comparison 视图中与基线对比
  • 关注 “#Delta” 列:新增对象数量和大小
  • 按 “Retained Size” 排序,找到最大的未释放对象

5. 分析保留路径

  • 点击对象 → 查看 “Retainers” 面板
  • 找到引用链:谁持有这个对象 → 为什么 GC 无法回收

关键指标

指标含义
Shallow Size对象自身占用的内存
Retained Size对象被 GC 回收后能释放的总内存(含其引用的子对象)
Distance对象到 GC 根的距离

最小例子

排查组件卸载后内存未释放:

// 有内存泄漏的代码
class ChartComponent {
  constructor() {
    this.data = new Array(100000).fill(0);
    this.resizeHandler = () => this.render();
    window.addEventListener('resize', this.resizeHandler);
  }

  // 忘记移除事件监听器
  destroy() {
    // 应该调用 window.removeEventListener('resize', this.resizeHandler)
  }
}

Memory 面板排查步骤:

  1. 拍快照 A
  2. 创建并销毁 10 次 ChartComponent
  3. 拍快照 B
  4. Comparison 视图中看到 ChartComponent 实例数量 = 10
  5. 查看 Retainers → 发现 resizeHandler 被 window 的事件监听器持有
  6. 修复:在 destroy 中 removeEventListener

常见内存泄漏模式

模式原因在 Memory 面板中的表现
闭包持有大对象闭包引用外部变量,函数未释放大量 Closure 对象,Retained Size 大
Detached DOMDOM 节点从文档移除但 JS 仍引用Heap snapshot 中搜 “Detached”
事件监听器未移除addEventListener 后未 removeEventListener对象被 EventTarget 的 listener 列表持有
定时器未清理setInterval/setTimeout 回调持有外部引用回调函数及其闭包持续存在
全局缓存无限增长Map/Set/Array 只增不删全局对象下的集合越来越大

边界与常见误解

  • 内存增长不等于泄漏:可能是缓存策略、GC 时机、或浏览器预分配;需多次快照对比确认
  • 单次快照意义有限:只看一份快照无法判断是否有泄漏,必须结合操作前后对比
  • GC 时机不可控:拍摄快照前可点击 “Collect garbage” 按钮手动触发 GC,确保结果准确
  • Memory 面板给的是”谁还活着”的证据:真正修复通常还要回到 Sources 面板 定位代码
  • DevTools 自身会增加内存开销:拍摄快照时会暂停页面,大页面可能卡顿数秒
  • Worker 内存不在面板中:Memory 面板只分析主线程堆内存,Web Worker 需单独分析

实用排障顺序

  1. 先确认是不是正常缓存或短期峰值
  2. 在关键操作前后各打一份快照
  3. 对比增长对象和保留路径(Retainers)
  4. 用 “Allocation on timeline” 看分配趋势确认持续增长
  5. 回到代码查事件监听、定时器、闭包和全局缓存
  6. 修复后再拍快照验证
创建于 2026/4/13 更新于 2026/5/27