← [ BACK_TO_NOTES ]

DevTools Memory 面板

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

#concept #growing #frontend #browser #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. 修复后再拍快照验证

学习检查

  1. Heap Snapshot、Allocation instrumentation、Allocation sampling 分别更适合回答什么问题?
  2. Shallow Size 与 Retained Size 为什么不能互换?
  3. Detached DOM 为什么只是线索,不自动等于内存泄漏?
  4. 为什么单次快照不能证明泄漏,必须结合重复操作和前后对比?
  5. Retainers 为什么是定位“谁让对象活着”的关键视图?
  6. 为什么内存持续升高可能来自缓存、预分配或 GC 时机,而不一定是泄漏?
  7. 给一个重复打开关闭 Dialog 后内存上涨的案例,设计 baseline → repeat → GC → snapshot comparison → retainers 的验证链。
创建于 2026/4/13 更新于 2026/9/30
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本