浏览器控制台 Memory 面板详细使用示例
1. 堆快照分析闭包泄漏
-
场景:单页应用中,切换页面后内存持续增长,怀疑闭包引用未释放。
-
操作步骤:
- 打开 Chrome 开发者工具 > Memory 面板,点击 Heap snapshot 拍摄初始快照。
- 执行页面跳转操作后,再次拍摄快照。
- 对比两次快照,筛选
Closure
类型对象,观察未被释放的闭包。
-
代码示例:
javascript
function createLeak() {
const data = new Array(100000).fill('leak'); // 大数组被闭包引用
return () => console.log(data); // 闭包未释放,导致 data 无法回收
}
const leakedFunc = createLeak();
// 即使不再使用 leakedFunc,内存仍被占用
- 优化 :手动解除引用(如
leakedFunc = null
)。
2. 时间线记录高频操作内存溢出
-
场景:频繁操作动画导致页面卡顿,需定位内存分配瓶颈。
-
操作步骤:
- 在 Memory 面板选择 Allocation instrumentation on timeline,点击开始录制。
- 执行高频操作(如快速滚动列表、频繁触发动画)。
- 停止录制后,观察时间线上的蓝色竖条(内存分配事件),定位到频繁分配临时对象的函数。
-
代码示例:
javascript
function renderFrame() {
const tempData = new Array(1000).fill({ x: Math.random() }); // 频繁创建临时对象
// ...渲染逻辑
}
setInterval(renderFrame, 16); // 60FPS 动画
- 优化:改用对象池复用临时对象。
3. DOM 节点未销毁导致内存残留
-
场景:动态弹窗关闭后,DOM 节点未被移除,内存占用持续增加。
-
操作步骤:
- 使用 Heap snapshot 拍摄弹窗打开前后的快照。
- 筛选
Detached DOM tree
(已脱离 DOM 树但未被回收的节点),检查弹窗相关div
节点。
代码示例:
javascript
function openModal() {
const modal = document.createElement('div');
document.body.appendChild(modal);
// 关闭时未执行 modal.remove()
}
4. 事件监听器未解绑引发泄漏
-
场景 :全局
resize
事件监听未移除,页面切换后回调函数仍占用内存。 -
操作步骤:
- 在堆快照中搜索
EventListener
对象。 - 对比页面切换前后的监听器数量,定位未解绑的事件。
- 在堆快照中搜索
javascript
window.addEventListener('resize', handleResize);
// 页面卸载时未执行 removeEventListener
- 优化 :在组件销毁或页面卸载时调用
removeEventListener
。
5. 分析大文件上传内存占用
-
场景:上传 1GB 文件时页面卡顿,需确认内存分配是否合理。
-
操作步骤:
- 使用 Allocation sampling 录制文件分片上传过程。
- 查看统计结果,分析
ArrayBuffer
或Blob
对象的分配频率和大小。
-
优化:
- 分片上传(如每片 2MB)25。
- 上传完成后主动释放内存:
file = null; URL.revokeObjectURL(url)
。