Ubuntu环境下基于日志的Node.js内存泄漏发现方法
一 建立可观测的内存指标日志
const fs = require('fs');
setInterval(() => {
const m = process.memoryUsage();
const msg = `${new Date().toISOString()}, RSS: ${(m.rss/1024/1024).toFixed(2)} MB, ` +
`HeapTotal: ${(m.heapTotal/1024/1024).toFixed(2)} MB, ` +
`HeapUsed: ${(m.heapUsed/1024/1024).toFixed(2)} MB, ` +
`External: ${(m.external/1024/1024).toFixed(2)} MB\n`;
fs.appendFileSync('memory.log', msg);
}, 1000);
top -p <PID>
# 或
htop
npm i -g pm2
pm2 start app.js --name myapp
pm2 monit
node --max-old-space-size=2048 app.js
以上步骤能在日志中形成稳定的内存时间序列,为后续判断是否泄漏提供依据。
二 从日志判定泄漏的模式
三 快速定位与快照分析
node --inspect app.js
npm i heapdump
# 代码中按需写快照
const heapdump = require('heapdump');
heapdump.writeSnapshot('/tmp/heap-' + Date.now() + '.heapsnapshot');
# 启动时开启信号触发
node --inspect --heapsnapshot-signal=SIGUSR2 app.js
# 生产环境发送信号
kill -SIGUSR2 <PID>
npm i memwatch-next
const memwatch = require('memwatch-next');
memwatch.on('leak', (info) => {
console.error('疑似泄漏:', info);
heapdump.writeSnapshot('/tmp/leak-' + Date.now() + '.heapsnapshot');
});
四 常见根因与修复要点
五 生产可操作的巡检流程
pm2 monit