在 javascript 运行时查看内存分配,最直接且准确的方法是使用 chrome devtools 的 memory 面板进行 heap snapshot(堆快照)对比分析。通过记录两个时间点的堆快照并生成差异报告,可以清晰看到哪些对象被分配、增长了多少以及它们的引用路径。此外,配合 performance 面板中的 allocation timeline 功能,可以实时观察内存随时间的波动情况,从而定位具体的代码执行片段。

如何通过堆快照对比定位内存泄漏
要确定内存中具体增加了哪些对象,需要获取两次堆快照并进行比较。首先打开 Chrome DevTools 切换到 Memory 标签页,点击“Take Heap Snapshot”按钮获取初始状态快照。接着触发可能导致内存增长的操作,例如点击页面按钮或执行一段循环代码。操作完成后再次点击“Take Heap Snapshot”获取第二个快照。在左侧的 Summary 列表中,选择第二个快照,并将 Comparison 下拉菜单设置为 “Comparison: [Second] vs [First]”。此时界面会显示一个表格,列出在第二次快照中新增的对象实例数量、总大小和保留大小(Retained Size)。通过展开这些对象,可以追踪到是谁引用了它们,从而找到未释放的引用源。

const largeArray = new Array(1000000).fill('data');
console.log('Initial memory:', performance.memory.usedJSHeapSize);
// 模拟内存增长
function allocateMemory() {
const leak = [];
for (let i = 0; i < 100000; i++) {
leak.push({ id: i, data: new Array(1000).join('x') });
}
// 故意不返回也不清理,模拟泄漏
return leak;
}
const leakedData = allocateMemory();
console.log('After allocation:', performance.memory.usedJSHeapSize);
// 注意:performance.memory 仅在 chrome://flags 启用如何实时监控内存分配的时间线
如果需要观察内存分配的具体时间点以及它与代码执行的对应关系,Performance 面板中的 Allocation Timeline 是更好的选择。在 Performance 标签页中,勾选 “Memory” 选项以启用内存采样。点击录制按钮开始捕获,然后执行你的应用程序逻辑。停止录制后,在底部的时间轴视图中,你会看到一个标记为 “JS Heap” 的图表。该图表显示了堆内存使用量随时间的变化曲线。当曲线出现阶梯式上升时,通常意味着发生了大量的内存分配。你可以将鼠标悬停在上升沿,DevTools 会显示具体的分配大小和时间戳。结合上方的 Call Stack 视图,可以查看在该时刻正在执行的函数调用栈,从而将内存分配行为与具体的代码行关联起来。
你是 TypeScript 项目架构专家,专注于脚手架搭建生产就绪的 Node.js 和前端应用。生成包含现代工具链(pnpm、Vite、Next.js)、类型
立即学习“Java免费学习笔记(深入)”;

// 性能监控示例代码
if (window.performance && window.performance.memory) {
setInterval(() => {
const mem = window.performance.memory;
console.log(`Used: ${(mem.usedJSHeapSize / 1024 / 1024).toFixed(2)} MB`);
console.log(`Total: ${(mem.totalJSHeapSize / 1024 / 1024).toFixed(2)} MB`);
}, 5000);
}当 Retained Size 远大于 Shallow Size 时说明什么
在堆快照对比结果中,如果某个对象的 Shallow Size(浅层大小)很小,但 Retained Size(保留大小)非常大,这通常说明该对象本身占用的内存不多,但它作为根节点或关键引用,持有大量其他对象的引用。这意味着如果释放了这个小对象,它所引用的所有大对象也将变得不可达并被垃圾回收。这种情况常见于全局缓存、事件监听器或未清空的数组。开发者应重点关注这类对象,检查是否有不必要的长生命周期引用,或者考虑使用弱引用(如 WeakMap 或 WeakSet)来避免阻止垃圾回收器回收被引用的对象。


















