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

Java使用GSON Streaming API解析超大JSON仍报OutOfMemoryError求助

超大JSON流式解析OutOfMemoryError问题优化方案

根本原因排查

你虽然用了GSON流式解析避免了全量JSON加载到内存,但解析后的全量业务数据依然全部驻留在堆内存中,是触发OOM的核心原因,具体问题点如下:

  • 全量解析结果存储在嵌套HashMap finalcycleTimeMap中,数据量级超过160万条后,HashMap的哈希表开销+存储的业务数据总大小超过了JVM堆内存上限
  • 代码存在多处不必要的序列化操作:每次循环都创建新的Gson实例序列化CycleTime对象打印,最后还会将全量结果Map序列化后打印,序列化生成的大字符串会临时占用大量堆内存
  • 解析逻辑存在缺陷:CycleTime对象全局只创建1次反复复用,且endObject存在重复调用的问题,可能导致解析逻辑错位,额外加载无效数据到内存
  • 未显式释放IO资源:InputStream、JsonReader用完后未关闭,可能产生资源泄漏占用内存

优化方案

  • 避免全量数据驻留内存:如果业务允许边解析边处理,解析单条CycleTime数据后直接执行业务逻辑(写入数据库、发送消息、实时计算等),不要将所有结果攒到Map中统一返回,从根源上解决内存占用问题
  • 移除冗余序列化操作:删除最后全量打印Map的序列化代码,循环中的对象打印仅输出必要关键字段,Gson实例改为单例全局复用,不要每次循环创建新实例
  • 修复解析逻辑缺陷:
    1. 每解析一条Report_Entry数组元素就创建一个新的CycleTime对象,避免脏数据和意外的内存持有
    2. 修正JsonReader的开闭逻辑:遍历数组元素时直接固定执行beginObject,读取完所有字段后再执行endObject,不要重复调用
  • 必须全量返回结果的场景优化:
    1. 调整JVM堆参数:根据数据量级放大最大堆内存,例如-Xmx8G -Xms8G
    2. 优化存储结构:将嵌套HashMap替换为更省内存的结构,比如直接存储CycleTime POJO,或者使用fastutil等内存优化的集合类,减少哈希表的额外开销
    3. 分页请求:如果上游接口支持分页,将单次全量请求拆分为多次分页请求,每次处理完一页数据后释放对应内存
  • 资源自动释放:使用try-with-resources语法管理InputStream和JsonReader,解析完成后自动关闭资源

修正后的核心解析代码示例

// 全局复用Gson实例
private static final Gson GSON = new Gson();

// 解析方法使用try-with-resources自动关闭资源
public void parseCycleTime(InputStream inputStream, CycleTimeConstant cycleTimeConstant, int processId) throws IOException {
    try (JsonReader reader = new JsonReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
        reader.beginObject();
        while (reader.hasNext()) {
            String name = reader.nextName();
            if ("Report_Entry".equals(name)) {
                reader.beginArray();
                int counter = 0;
                while (reader.hasNext()) {
                    // 每条数据新建对象
                    CycleTime cycleTime = new CycleTime();
                    reader.beginObject();
                    while (reader.hasNext()) {
                        String fieldName = reader.nextName();
                        switch (fieldName) {
                            case "key1":
                                cycleTime.setKey1(reader.nextString());
                                break;
                            case "key2":
                                cycleTime.setKey2(reader.nextString());
                                break;
                            case "key3":
                                cycleTime.setKey3(reader.nextString());
                                break;
                            case "key4":
                                cycleTime.setKey4(reader.nextString());
                                break;
                            case "key5":
                                cycleTime.setKey5(reader.nextString());
                                break;
                            default:
                                // 跳过不需要的字段
                                reader.skipValue();
                        }
                    }
                    reader.endObject();
                    counter++;
                    // 边解析边处理,不要攒到Map里
                    processSingleCycleTime(cycleTime, cycleTimeConstant, counter, processId);
                    // 仅打印必要信息
                    if (counter % 10000 == 0) {
                        System.out.println("已解析条数:" + counter);
                    }
                }
                reader.endArray();
            } else {
                // 跳过根节点下不需要的字段
                reader.skipValue();
            }
        }
        reader.endObject();
    }
}

// 单条数据业务处理逻辑
private void processSingleCycleTime(CycleTime cycleTime, CycleTimeConstant cycleTimeConstant, int counter, int processId) {
    // 实现你的业务逻辑,比如写库、计算等
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 22:15:03