You need to enable JavaScript to run this app. Node.js循环发送UDP包引发内存泄漏导致进程OOM崩溃
优惠活动
大模型
产品
解决方案
定价
更多

Node.js循环发送UDP包引发内存泄漏导致进程OOM崩溃

Node.js UDP发包触发堆内存溢出的修复方案

根因梳理

  • 阻塞式同步while(true)会完全占满Node.js主线程,事件循环无法进入IO回调、GC执行阶段,所有循环内创建的对象都会被常驻上下文持有,无法被回收
  • 同步循环中无限制触发dgram.send()异步接口,会导致JS层待发送队列、内核UDP发送缓冲区无限堆积,且因为主线程被阻塞,回调永远无法执行,队列中的数据包无法被释放
  • 循环内反复创建新的Buffer、回调闭包,且没有及时释放引用,进一步加剧短生命周期对象的内存占用,最终触发V8堆内存溢出

核心注意点:即使后续实现布尔开关控制,也不能直接把同步代码改成while(shouldSend),只要同步循环持续占用线程,依然会出现阻塞、内存堆积的问题

分步修复实现

替换阻塞循环为非阻塞调度逻辑

  • 绝对不能在主执行流中使用同步while(shouldSend)结构,即使加了布尔判断,只要循环持续运行就会阻塞事件循环
  • 采用事件驱动的启停控制,通过全局布尔状态控制非阻塞循环的启动/停止,示例代码如下:
const dgram = require('dgram');
const udpClient = dgram.createSocket('udp4');
let shouldSend = false;
let loopTask = null;
// 提前预分配发送用Buffer,全局复用,避免反复创建短生命周期对象
const SEND_BUFFER = Buffer.alloc(512);

// 发包循环函数
function sendLoop() {
  // 开关为false时直接退出,清空调度任务引用
  if (!shouldSend) {
    loopTask = null;
    return;
  }
  // 直接复用预分配的Buffer,按需填充发送内容
  SEND_BUFFER.write('test udp payload');
  udpClient.send(
    SEND_BUFFER,
    0,
    SEND_BUFFER.length,
    9000,
    '127.0.0.1',
    (err) => {
      // 回调中仅处理必要逻辑,不持有大对象引用
      if (err) console.error('send error:', err.message);
    }
  );
  // 将下一轮循环调度到事件循环的空闲阶段,不阻塞主线程
  loopTask = setImmediate(sendLoop);
}

// 对外暴露的启停接口
function startSending() {
  if (!shouldSend) {
    shouldSend = true;
    sendLoop();
  }
}
function stopSending() {
  shouldSend = false;
  if (loopTask) {
    clearImmediate(loopTask);
    loopTask = null;
  }
}

内存泄漏专项优化

  • 固定复用Buffer等全局对象,禁止在循环内反复调用Buffer.alloc()创建新实例,降低GC压力
  • 对发包频率做限流:如果不需要极致发包速度,可将递归setImmediate替换为setInterval,控制单秒发包量,避免待发送队列瞬间堆积
  • 确保UDP socket的事件监听仅绑定一次,禁止在循环内反复绑定error、close等事件,防止闭包引用无法被GC回收
  • 停止发包时务必清空调度任务的引用,避免残留任务继续触发发包逻辑占用内存

实现验证方法

  • 对比修复前后的GC日志:非阻塞实现生效后,老生代内存会保持在稳定区间,不会出现无限制增长
  • 通过系统工具观测UDP发送队列长度,当队列堆积超过阈值时,主动降低发包频率,避免内核缓冲区占用过高内存
  • 对比Node.js堆内存快照,确认没有大量滞留的Buffer、UDP发送上下文对象

内容的提问来源于stack exchange,提问作者asd12tgzxvbgt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.12 19:45:02