首先需要通过工具监控内存使用趋势,判断是否存在持续增长且不释放的情况(正常应用的内存使用会在GC后趋于稳定)。
top、htop(需安装,sudo apt install htop)实时查看进程的RES(常驻内存)列,若内存持续上升且不回落,可能存在泄漏。pm2(npm install pm2 -g)启动应用,执行pm2 monit查看内存、CPU等指标的实时变化。process.memoryUsage()定时打印,观察heapUsed(已使用的堆内存)是否持续增长。例如:setInterval(() => {
const memory = process.memoryUsage();
console.log(`RSS: ${(memory.rss / 1024 / 1024).toFixed(2)}MB, HeapUsed: ${(memory.heapUsed / 1024 / 1024).toFixed(2)}MB`);
}, 5000);
堆快照是分析内存泄漏的核心依据,它能展示当前内存中的所有对象及其引用关系。常用工具:
--inspect参数(node --inspect app.js),然后在Chrome浏览器访问chrome://inspect,点击“Open dedicated DevTools for Node”,切换到Memory面板,点击“Take heap snapshot”生成快照。npm install heapdump,在代码中引入并在关键位置(如怀疑泄漏的代码前后、定时任务中)生成快照:const heapdump = require('heapdump');
heapdump.writeSnapshot(`/tmp/snapshot-${Date.now()}.heapsnapshot`);
快照文件会保存在指定路径,可通过DevTools导入分析。使用Chrome DevTools的Memory面板分析堆快照,重点关注:
global对象或未声明的变量);setInterval/setTimeout)未清除;EventEmitter)未移除;根据分析结果针对性修复:
let/const,避免直接挂载到global对象;及时删除不再需要的全局变量(如delete global.unusedVar)。clearInterval(timerId)/clearTimeout(timeoutId)清除定时器。removeListener或off方法中移除不再需要的监听器(如emitter.removeListener('event', listener));使用once方法替代on,确保监听器只执行一次。lru-cache模块),定期清理过期缓存。修复后重新运行应用,重复步骤1(监控内存)和步骤2(生成快照),观察内存使用是否趋于稳定(无持续增长),快照中的可疑对象是否消失或数量减少。若仍有泄漏,需重复上述步骤进一步分析。
npm install -g clinic
clinic heapprofiler -- node app.js
运行后按Ctrl+C停止,自动生成报告并在浏览器中打开,通过火焰图分析内存泄漏的热点函数。autocannon(npm install autocannon -g)模拟高并发请求,暴露潜在的内存泄漏问题:autocannon -c 100 -d 30 http://localhost:3000/api/leaky-endpoint
结合内存监控工具,观察高负载下内存的增长情况。通过以上步骤,可以系统性地排查和解决Ubuntu环境下Node.js应用的内存泄漏问题。关键是持续监控内存趋势、精准定位泄漏点、针对性修复并验证,确保应用内存使用稳定。