温馨提示×

ubuntu nodejs内存泄漏咋查

小樊
52
2026-09-19 00:41:11
栏目: 编程语言

在 Ubuntu 上排查 Node.js 内存泄漏,通常分 “定位现象 → 抓取数据 → 分析根因 → 验证修复” 四步。下面给你一套实战可用的方案。


一、先确认是不是内存泄漏

1. 看内存趋势

top -p $(pidof node)
# 或
htop

重点看 RES / RSS 是否持续上涨,GC 后也不回落。

2. 开启 Node 自带内存监控

setInterval(() => {
  const used = process.memoryUsage();
  console.log({
    rss: used.rss / 1024 / 1024 + 'MB',
    heapTotal: used.heapTotal / 1024 / 1024 + 'MB',
    heapUsed: used.heapUsed / 1024 / 1024 + 'MB',
  });
}, 5000);

如果 heapUsed 只增不减,大概率泄漏。


二、抓取内存快照(最关键)

方式 1:heapdump(推荐)

npm i heapdump
const heapdump = require('heapdump');
setInterval(() => {
  heapdump.writeSnapshot('/tmp/heap-' + Date.now() + '.heapsnapshot');
}, 60000);

对比 两个时间点的 snapshot:

  • 增长最多的对象类型
  • 被谁引用(Retainers)

方式 2:Node 自带 inspector(不重启)

node --inspect=9229 app.js

Chrome 打开:

chrome://inspect
  • Take Heap Snapshot
  • 对比 Snapshot

方式 3:生产环境安全方式

kill -USR2 <pid>

(配合 node --expose-gc)


三、常见内存泄漏原因(重点看)

1. 全局变量

global.cache = {};

2. 闭包引用

function leak() {
  const big = new Array(1e6);
  return () => big;
}

3. 事件监听器未移除

emitter.on('data', handler);
// 没有 off

4. 定时器

setInterval(() => {}, 1000);

5. 缓存无限增长

const map = new Map();
map.set(key, value);

✅ 解决:

  • LRU cache
  • WeakMap / WeakRef

四、Ubuntu 特有注意点

1. 系统 OOM

dmesg | grep -i oom
journalctl -k | grep oom

2. 限制内存

node --max-old-space-size=512 app.js

3. Docker 场景

ENV NODE_OPTIONS=--max-old-space-size=512

五、分析工具推荐

工具 用途
Chrome DevTools 快照对比
heapdump 生成快照
clinic.js 综合诊断
memwatch-next 自动检测
npm i -g clinic
clinic heap app.js

六、快速排查 checklist

✅ 是否监听未移除
✅ 是否有全局 cache
✅ 是否有闭包持有大对象
✅ 是否有 setInterval
✅ 是否第三方库泄漏


如果你愿意,可以:

  • 贴 Node 版本
  • 贴 代码片段
  • 或 heapsnapshot 截图

我可以直接帮你定位是哪一行导致的泄漏。

0 踩