在 Ubuntu 上排查 Node.js 内存泄漏,通常分 “定位现象 → 抓取数据 → 分析根因 → 验证修复” 四步。下面给你一套实战可用的方案。
top -p $(pidof node)
# 或
htop
重点看 RES / RSS 是否持续上涨,GC 后也不回落。
setInterval(() => {
const used = process.memoryUsage();
console.log({
rss: used.rss / 1024 / 1024 + 'MB',
heapTotal: used.heapTotal / 1024 / 1024 + 'MB',
heapUsed: used.heapUsed / 1024 / 1024 + 'MB',
});
}, 5000);
如果 heapUsed 只增不减,大概率泄漏。
npm i heapdump
const heapdump = require('heapdump');
setInterval(() => {
heapdump.writeSnapshot('/tmp/heap-' + Date.now() + '.heapsnapshot');
}, 60000);
对比 两个时间点的 snapshot:
node --inspect=9229 app.js
Chrome 打开:
chrome://inspect
kill -USR2 <pid>
(配合 node --expose-gc)
global.cache = {};
function leak() {
const big = new Array(1e6);
return () => big;
}
emitter.on('data', handler);
// 没有 off
setInterval(() => {}, 1000);
const map = new Map();
map.set(key, value);
✅ 解决:
dmesg | grep -i oom
journalctl -k | grep oom
node --max-old-space-size=512 app.js
ENV NODE_OPTIONS=--max-old-space-size=512
| 工具 | 用途 |
|---|---|
| Chrome DevTools | 快照对比 |
| heapdump | 生成快照 |
| clinic.js | 综合诊断 |
| memwatch-next | 自动检测 |
npm i -g clinic
clinic heap app.js
✅ 是否监听未移除
✅ 是否有全局 cache
✅ 是否有闭包持有大对象
✅ 是否有 setInterval
✅ 是否第三方库泄漏
如果你愿意,可以:
我可以直接帮你定位是哪一行导致的泄漏。