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

Node.js堆内存溢出求助:大JSON对象写入失败

解决Node.js大对象JSON序列化内存溢出问题

你的问题根源很明确:JSON.stringify(o)会一次性把整个百万级对象转换成一个超大字符串,这个字符串完全占用堆内存——哪怕后面用流式写入也已经晚了,内存早就被巨量的字符串占满,自然触发堆内存不足的致命错误。

下面给你两个实用的解决方案:

方案一:使用流式JSON序列化库(推荐)

第三方库stream-json专门解决这类问题,它可以边遍历对象边输出JSON内容,不会把完整的JSON字符串加载到内存中,内存占用极低。

步骤:

  1. 先安装依赖:
npm install stream-json
  1. 修改你的保存函数:
const fs = require('fs');
const { stringify } = require('stream-json/Stringer');

function saveObjectAsJSON(o, filename) {
  const writeStream = fs.createWriteStream(filename);
  // 将对象序列化流直接管道到文件写入流
  stringify(o).pipe(writeStream);
}

这个方法不管你的大对象是数组还是嵌套结构,都能完美处理,底层会自动分块处理数据,完全避免内存溢出。

方案二:手动分块处理(无第三方依赖)

如果你的外层对象是包含百万条数据的数组,可以手动遍历数组,逐个序列化每个元素,再拼接成合法的JSON数组格式,这样每次内存中只保留单个元素的JSON字符串。

示例代码:

const fs = require('fs');

async function saveLargeArrayAsJSON(largeArray, filename) {
  const writeStream = fs.createWriteStream(filename);
  
  // 先写入JSON数组的开头
  writeStream.write('[');
  
  for (let index = 0; index < largeArray.length; index++) {
    const item = largeArray[index];
    const itemJson = JSON.stringify(item);
    
    // 除了第一个元素,前面要加逗号分隔符
    if (index > 0) {
      writeStream.write(',');
    }
    
    // 写入当前元素的JSON
    writeStream.write(itemJson);
    
    // 每处理1000条就等待流排空,避免内部缓冲堆积
    if (index % 1000 === 0) {
      await new Promise(resolve => writeStream.once('drain', resolve));
    }
  }
  
  // 写入JSON数组的结尾
  writeStream.write(']');
  writeStream.end();
}

注意事项:

  • 这个方法只适用于外层是数组的情况,如果是复杂嵌套对象,手动处理格式会非常繁琐,还是推荐方案一。
  • 加入drain事件的等待是为了防止写入流的内部缓冲溢出,保证写入过程稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:21:15