首先需要通过系统工具或代码监控,确认应用是否存在内存持续增长且不释放的情况(内存泄漏的核心特征)。
top、htop或ps命令查看Node.js进程的内存使用(RES列代表物理内存占用)。若进程内存随时间持续上升(如运行1小时后内存翻倍),则可能存在泄漏。示例命令:top -p $(pgrep -f "node app.js") # 监控指定Node.js进程的内存
ps -p <PID> -o %mem,vsz,rss # 查看进程内存占比、虚拟内存、物理内存
process.memoryUsage()方法,定期记录内存使用情况(单位:字节),观察heapUsed(堆内存使用量)或rss(常驻内存集)的增长趋势。示例:setInterval(() => {
const memory = process.memoryUsage();
console.log(`Heap Used: ${(memory.heapUsed / 1024 / 1024).toFixed(2)} MB`);
}, 5000); // 每5秒打印一次
内存快照是分析内存泄漏的关键工具,它能捕获当前堆内存中的所有对象及其引用关系,帮助定位未被释放的对象。
--inspect或--inspect-brk标志(--inspect-brk会在启动时暂停,便于调试):node --inspect app.js
chrome://inspect,点击“Open dedicated DevTools for Node”连接进程。npm install heapdump。const heapdump = require('heapdump');
heapdump.writeSnapshot('/tmp/snapshot_' + Date.now() + '.heapsnapshot');
/tmp),可通过Chrome DevTools导入分析。使用Chrome DevTools的“Memory”面板分析快照,重点关注内存增长的对象和异常引用链:
global或未声明的变量(如global.cache = {})。EventEmitter监听器(如emitter.on('event', callback))。Map、Array未设置大小限制)。根据快照分析结果,重点检查以下常见内存泄漏场景:
let/const替代var),避免意外挂载到global对象。emitter.off()或removeListener()移除监听器。lru-cache模块),或使用WeakMap/WeakSet(弱引用,不会阻止GC)。fs.readFile后调用stream.destroy())。leak事件并生成快照。示例:const memwatch = require('memwatch-next');
memwatch.on('leak', (info) => {
console.error('Memory leak detected:', info);
memwatch.writeSnapshot('/tmp/leak_snapshot.heapsnapshot');
});
sudo apt install heaptrack)。valgrind --leak-check=full node app.js)。通过以上步骤,可系统性地定位和解决Linux环境下JavaScript应用的内存泄漏问题。关键是结合工具分析与代码审查,从根源上消除内存泄漏的诱因。