You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js应用出现JavaScript堆内存溢出问题求解决方案

解决Node.js堆内存耗尽(Reached heap limit Allocation failed)问题的思路

你的代码引发内存溢出的核心原因是一次性加载了大量media文档到内存,加上未等待save操作完成导致Promise堆积,最终耗尽堆内存。以下是具体修复方案:

1. 分页查询,避免一次性加载全量数据

如果medias数据量很大,this.mediaModel.find()会把所有MongoDB文档加载到内存中,直接占用大量堆空间。改成分页分批处理,每次只加载固定数量的文档,处理完再加载下一批:

async updateLinks() {
  this.logger.log('Cron Job: Updating Urls .....')
  const batchSize = 50; // 根据服务器内存调整批次大小
  let skip = 0;
  let hasMore = true;

  while (hasMore) {
    // 分页查询
    const medias = await this.mediaModel.find().skip(skip).limit(batchSize);
    if (medias.length === 0) {
      hasMore = false;
      break;
    }

    // 逐批处理
    for (let media of medias) {
      const url = await this.testService.getPreSignedUrl(media.key);
      media.url = url;
      await media.save(); // 必须等待保存完成,避免Promise堆积
    }

    skip += batchSize;
    // 可选:手动触发垃圾回收(需启动时加--expose-gc参数)
    global.gc?.();
  }
  this.logger.log('Cron Job: Completed ')
}

2. 等待save操作完成

原代码中media.save()没有加await,会导致大量未完成的保存Promise同时存在,每个Promise都会占用内存资源。加上await确保每个保存操作完成后再处理下一个文档,避免内存堆积。

3. 控制S3请求并发数(可选,兼顾效率与内存)

如果想提高处理效率,同时避免并发过高导致内存占用飙升,可以在批次内控制并发请求数:

// 在分页循环内替换原for循环
const concurrency = 10; // 控制同时发起10个S3请求和保存操作
for (let i = 0; i < medias.length; i += concurrency) {
  const subBatch = medias.slice(i, i + concurrency);
  await Promise.all(subBatch.map(async media => {
    const url = await this.testService.getPreSignedUrl(media.key);
    media.url = url;
    return media.save();
  }));
}

4. 临时应急:增加堆内存上限

如果需要快速临时解决,可以在启动Node.js应用时增加堆内存限制,比如设置为4GB:

node --max-old-space-size=4096 your-app.js

注意:这只是临时方案,无法根治数据量过大的问题,最终还是要通过代码优化解决。

5. 排查内存泄漏

如果优化后仍有问题,可以用Node.js调试工具排查内存泄漏:

  • 启动应用时添加--inspect参数
  • 在Chrome浏览器中打开chrome://inspect,连接到应用
  • 使用Memory面板生成内存快照,查看是否有大量未被回收的media实例或其他对象

内容的提问来源于stack exchange,提问作者Илья Никитин

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:08:23