要解决内存泄漏,首先需要定位泄漏源,以下是CentOS环境下常用的工具组合:
npm install heapdump --save。heapdump.writeSnapshot('/path/to/snapshot.heapsnapshot')手动生成堆快照(或在代码中设置定时器定期生成)。生成的.heapsnapshot文件可通过Chrome浏览器打开,利用Chrome DevTools的Memory面板分析内存中的对象分布,找出异常增长的对象(如未被释放的全局变量、缓存等)。node --inspect app.js启动应用,然后在Chrome中访问chrome://inspect,连接至Node.js进程,使用Memory面板的“Heap Snapshot”功能捕获实时内存状态,对比不同时间点的快照,识别内存泄漏的对象。clinic heapprofiler -- node server.js启动分析,Ctrl+C停止后会生成可视化火焰图。火焰图的X轴表示时间/样本数量,Y轴表示调用栈深度,宽度表示内存占用比例,通过观察宽且持续的函数调用(如某个模块的频繁内存分配),快速定位泄漏根源。定位到泄漏源后,需针对性修复,常见原因及解决方法如下:
global.xxx = data),使用let/const替代var声明变量,确保变量在作用域内被回收。EventEmitter实例(如http.Server、fs.FSWatcher),在不需要时调用removeListener或removeAllListeners移除监听器,防止内存持续占用。fs.close)、数据库连接(如mongoose.connection.close)、套接字(socket.destroy)等资源,避免资源句柄泄漏。lru-cache模块),定期清理过期缓存,避免缓存无限增长占用内存。通过监控工具定期检查内存使用情况,及时发现泄漏趋势:
top、htop(需安装:yum install htop)、vmstat 1(每秒刷新一次内存统计)命令,查看Node.js进程的RES(常驻内存)或%MEM(内存占比)是否持续增长。process.memoryUsage()定期输出内存使用信息(如heapUsed、heapTotal、rss),例如:setInterval(() => {
const memory = process.memoryUsage();
console.log(`Heap Used: ${(memory.heapUsed / 1024 / 1024).toFixed(2)}MB`);
}, 5000);
memwatch-next监控内存泄漏,安装后添加以下代码:const memwatch = require('memwatch-next');
memwatch.on('leak', (info) => {
console.error('Memory leak detected:', info);
});
--max-old-space-size参数调整(单位:MB),例如:node --max-old-space-size=4096 app.js # 设置为4GB
或通过环境变量设置:export NODE_OPTIONS="--max-old-space-size=4096"
注意:此方法仅为临时缓解,需结合泄漏修复使用。node -p "process.arch"验证,输出x64即为64位)。pm2 start app.js --max-memory-restart 4G # 内存超过4GB时自动重启
PM2还支持内存监控(pm2 monit)和日志分析。cluster模块,将应用分布在多个CPU核心上,分散单个进程的内存压力。例如:const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
for (let i = 0; i < numCPUs; i++) cluster.fork();
} else {
require('./app.js'); // 子进程运行应用
}
sudo fallocate -l 4G /swapfile # 创建4G交换文件
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab # 永久生效
autocannon或artillery模拟高并发请求,结合内存分析工具(如Clinic.js),在接近生产环境的场景下检测内存泄漏。