Node.js 中使用 worker_threads 处理 CPU 密集型任务时的内存泄漏排查
线上有个图片处理服务最近频繁 OOM,重启后跑十几个小时内存就涨到 1.5G 左右,容器限制是 2G,再涨就直接被 kill。服务本身逻辑不复杂:接收上传的图片,交给 worker_threads 做缩略图生成和格式转换,主线程只做 I/O 和队列调度。最初怀疑是图片缓冲区没释放,排查后发现主线程的 Buffer 都已经正常回收,堆快照里也没有明显的大对象。真正的问题藏在 worker 的生命周期管理上——每次任务都 new 一个 Worker,用完调用 terminate(),但 terminate 是异步的,大量并发下 worker 还没真正退出,新的 worker 又在创建,加上 worker 内部加载的 sharp 原生模块会占用外部内存,堆外内存的增长在 Node 的 heap snapshot 里根本看不到。这篇文章记录这次排查的过程,涉及 worker_threads 的复用策略、terminate 与 exit 的时序问题,以及如何用 process.memoryUsage 和 --inspect 定位堆外内存。