1. 识别内存泄漏
在Debian系统上,首先需要确认Node.js应用是否存在内存泄漏。常用方法包括:
process.memoryUsage()监控:通过定期打印rss(常驻内存集)、heapUsed(堆内存使用量)等指标,观察内存是否持续增长(如每秒增长超过10MB且无下降趋势)。示例代码:setInterval(() => {
  const { rss, heapUsed } = process.memoryUsage();
  console.log(`RSS: ${(rss / 1024 / 1024).toFixed(2)}MB, HeapUsed: ${(heapUsed / 1024 / 1024).toFixed(2)}MB`);
}, 1000);
node-memwatch库,它会自动检测内存泄漏并发出警报。安装后添加监听:const memwatch = require('node-memwatch');
memwatch.on('leak', (info) => console.error('Memory leak detected:', info));
2. 分析内存泄漏根源
定位泄漏的具体原因是解决问题的关键,常用工具和方法:
heapdump模块生成堆快照(.heapsnapshot文件),通过Chrome DevTools加载并对比多个快照,找出Retainers(引用链)中持续存在的对象。安装与使用:npm install heapdump
const heapdump = require('heapdump');
heapdump.writeSnapshot('/tmp/snapshot_' + Date.now() + '.heapsnapshot');
let/const/var声明的变量)、闭包引用(回调函数中保留了大对象引用)、未移除的事件监听器(如EventEmitter的on未对应removeListener)、无限增长的缓存(如Map/Object未设置过期策略)。3. 修复内存泄漏问题
针对不同类型的泄漏,采取对应的修复措施:
let/const),避免未声明的变量成为全局对象的属性。null。removeListener或off方法移除事件监听器。示例:const EventEmitter = require('events');
const emitter = new EventEmitter();
const callback = () => console.log('Event triggered');
emitter.on('event', callback);
// 不再需要时移除
emitter.removeListener('event', callback);
lru-cache等库实现有限大小的缓存,设置max(最大条目数)和maxAge(过期时间),自动淘汰不常用的缓存。示例:const LRU = require('lru-cache');
const cache = new LRU({ max: 1000, maxAge: 1000 * 60 * 15 }); // 15分钟过期
cache.set('key', 'value');
clearInterval/clearTimeout清除不再需要的定时器,避免回调函数持续持有对象引用。4. 监测与预防复发
建立长效的监测和预防机制,避免内存泄漏再次发生:
pm2等进程管理工具监控Node.js应用的内存使用情况,设置内存阈值(如--max-memory-restart 800M),超过阈值时自动重启进程。安装与启动:npm install pm2 -g
pm2 start app.js --max-memory-restart 800M
autocannon等工具进行负载测试,模拟高并发场景,提前发现内存泄漏问题。安装与使用:npm install -g autocannon
autocannon -c 100 -d 30 http://localhost:3000/api/endpoint
--max-old-space-size参数,单位为MB),避免因内存不足导致进程崩溃。示例:node --max-old-space-size=4096 app.js