问题背景
线上服务每运行 6 小时后内存持续增长,最终 OOM。
排查过程
1. 确认问题
[object Object], node --inspect app.js
通过 Chrome DevTools 的 Memory 面板发现 EventEmitter 的 listener 数量异常增长。
2. 定位根源
[object Object], ,[object Object], ,[object Object],(,[object Object],) { emitter.,[object Object],(,[object Object],, ,[object Object], { res.,[object Object],(data); }); }
3. 修复方案
[object Object], ,[object Object], ,[object Object],(,[object Object],) { ,[object Object], ,[object Object], = (,[object Object],) => { res.,[object Object],(data); emitter.,[object Object],(,[object Object],, handler); ,[object Object], }; emitter.,[object Object],(,[object Object],, handler); }
总结
- EventEmitter 的 listener 泄漏是 Node.js 内存泄漏最常见原因之一
- 使用
emitter.setMaxListeners(0)只是掩盖问题,不是解决方案 - 推荐使用
once()代替on()处理一次性事件