容器 limit 是 2Gi,启动参数写了 --max-old-space-size=4096,跑半小时还是被 OOMKilled,退出码 137。进程里 heapUsed 只有 600MB。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
node --max-old-space-size=1200 app.js node -e "console.log(process.memoryUsage())"
堆上限只是 V8 老生代的上限,Buffer、ArrayBuffer 和原生模块分配的内存在堆外,不计入 heapUsed。上限设得比容器 limit 还大,进程会先被内核杀掉。这一点先确认清楚,后面就不用反复试。
碰到「Node 堆上限与 RSS」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。
备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。
偶发问题先统计频率,一小时几次和一天一次,查法完全不同。
具体做法是,把 max-old-space-size 压在容器 limit 的六成左右 给堆外留空间;用 process.memoryUsage 分别看 rss heapUsed external;大 Buffer 用完及时置空 不要长期挂在缓存里;确认 limit 和 request 不是同一个值。
改完照着核一遍,运行两小时 rss 稳定在 1.5GB 以下 不再出现退出码 137。
