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

Node.js中保存大文件最节省内存的实现方案是什么?

错误原因

你给出的错误

20 error code ELIFECYCLE
21 error errno 137

是典型的Linux系统OOM Killer(内存溢出终止进程)触发的报错:当进程占用内存超出系统可用内存阈值时,内核会主动杀掉内存占用最高的进程释放资源,对应进程退出码就是137。

你当前使用fs.writeFileSync()写50MB JSON触发OOM的核心原因是:该方法要求你先把完整的JSON数据全量序列化为字符串后才能写入,JSON.stringify()处理大体积JSON对象时会生成大量临时变量,实际内存占用会远高于JSON本身的50MB大小。1GB内存的云服务器本身还要承载系统进程、其他服务的内存开销,剩余可用内存不足以支撑全量序列化的开销,就会触发报错,高配笔记本内存充足所以不会出现该问题。

低内存写入方案
  • 流式序列化写入(最推荐)
    不要一次性加载全量JSON数据到内存、全量序列化,改为边生成单条数据边写入磁盘,内存中仅保留当前正在处理的单条数据,内存占用可以降到KB级别,完全规避大内存开销。示例实现如下:
const fs = require('fs');
// 创建文件可写流
const writeStream = fs.createWriteStream('./output.json');

// 写入JSON根结构开头,如根结构是对象则写'{',是数组则写'['
writeStream.write('[');
// 替换为你自己的数据源迭代逻辑,比如逐行读取数据库、逐行读取源文件,每次仅返回单条数据,不要一次性加载全量
const dataIterator = yourBusinessDataGenerator();
let isFirstItem = true;

for (const item of dataIterator) {
  // 非第一条数据先加逗号分隔
  if (!isFirstItem) writeStream.write(',');
  isFirstItem = false;
  // 仅序列化当前单条数据写入
  writeStream.write(JSON.stringify(item));
}

// 写入JSON根结构结尾,和开头对应
writeStream.write(']');
// 关闭可写流,结束写入
writeStream.end(() => {
  console.log('JSON文件写入完成');
});
  • 临时调整Node堆内存上限(临时解决方案)
    如果暂时无法修改数据生成逻辑,可以在启动Node脚本时增加参数调高V8堆内存上限,适配1GB内存的服务器可以设置为768MB:
    node --max-old-space-size=768 your-script.js
    该方案为临时解决方案,当数据量继续上涨时还是会触发OOM问题。
  • 清理冗余缓存
    检查业务逻辑中是否存在把完整JSON对象、序列化后的全量字符串多份缓存的逻辑,删除冗余缓存变量也能降低内存开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:18:03