CodeWalk

Node.js 内存泄漏排查工具与方法(heapdump/clinic)

作者:小字辈 · 2026-05-30 12:55

请说明 Node.js 应用常见的几种内存泄漏场景(全局变量/闭包/定时器/事件监听器),以及如何使用 heapdump、clinic.js、Chrome DevTools 等工具进行排查。

回答

小字辈

常见内存泄漏场景

  1. 全局变量:意外将大对象挂在 global
  2. 未清除的定时器setInterval 回调持有引用
  3. 未移除的事件监听器EventEmitter.on() 未调用 off()
  4. 闭包引用:函数持有大对象的外层作用域引用
  5. 缓存无限增长:未设上限的 Map/WeakMap
  6. Stream 未消费:可读流未监听 data 或 pipe 导致内存堆积

排查工具

1. heapdump:生成堆快照

const heapdump = require('heapdump');

// 通过信号触发
process.kill(process.pid, 'SIGUSR2');
// 或定时
setInterval(() => {
  heapdump.writeSnapshot('/tmp/heap-' + Date.now() + '.heapsnapshot');
}, 60000);
  • 在 Chrome DevTools → Memory 中加载 .heapsnapshot
  • 比较两个快照(前/后)分析对象增长

2. clinic.js:诊断工具套件

npx clinic doctor -- node app.js
# 生成可视化报告,定位泄漏源
npx clinic flame -- node app.js   # 火焰图分析 CPU
npx clinic heap -- node app.js    # 内存分配分析

3. Chrome DevTools(--inspect)

node --inspect app.js
# Chrome 打开 chrome://inspect → Open dedicated DevTools
# Memory 面板:Allocation instrumentation on timeline

4. process.memoryUsage()

setInterval(() => {
  const mem = process.memoryUsage();
  console.log(`RSS: ${mem.rss / 1024 / 1024} MB`);
  console.log(`Heap: ${mem.heapUsed / 1024 / 1024} MB / ${mem.heapTotal / 1024 / 1024} MB`);
  // heapUsed 持续增长暗示泄漏
}, 5000);

预防:使用 WeakRef/FinalizationRegistry、设置缓存上限、确保 addEventListener/on 配对 off。