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

如何使用kotlinx.serialization递归/增量解析45MB大型JSON文件

Android超大JSON解析内存优化方案

核心思路:流式解析,避免全量加载

不管用原生还是第三方库,核心都是不把整个JSON文件加载到内存,而是逐元素读取、处理、释放,这样内存占用能控制在几MB级别。

方案1:Android原生JsonReader(无依赖)

直接用Android SDK自带的JsonReader,从InputStream读取流,逐个解析JSON元素:

// 从文件获取InputStream,避免把整个文件读成String
File jsonFile = new File(getFilesDir(), "large_data.json");
InputStream inputStream = new FileInputStream(jsonFile);
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));

try {
    reader.beginArray(); // 假设根节点是数组,根据实际JSON结构调整
    while (reader.hasNext()) {
        // 逐个解析单个对象,处理完立即释放
        DataModel model = readSingleModel(reader);
        // 处理model:比如插入数据库、写入文件等,不要存到全局List中
        processModel(model);
    }
    reader.endArray();
} finally {
    reader.close();
    inputStream.close();
}

// 解析单个对象的方法
private DataModel readSingleModel(JsonReader reader) throws IOException {
    DataModel model = new DataModel();
    reader.beginObject();
    while (reader.hasNext()) {
        String name = reader.nextName();
        switch (name) {
            case "id":
                model.setId(reader.nextLong());
                break;
            case "name":
                model.setName(reader.nextString());
                break;
            // 其他字段按需解析
            default:
                reader.skipValue(); // 跳过不需要的字段,节省内存
                break;
        }
    }
    reader.endObject();
    return model;
}

方案2:Gson流式解析(适合用Gson的项目)

如果项目依赖Gson,同样用它的JsonReader做流式解析,不要用fromJson直接转成整个集合:

Gson gson = new Gson();
File jsonFile = new File(getFilesDir(), "large_data.json");
InputStream inputStream = new FileInputStream(jsonFile);
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));

try {
    reader.beginArray();
    while (reader.hasNext()) {
        // 逐个解析对象,处理后立即释放
        DataModel model = gson.fromJson(reader, DataModel.class);
        processModel(model);
    }
    reader.endArray();
} finally {
    reader.close();
    inputStream.close();
}

关键注意事项

  • 绝对不要把JSON文件转成String再解析:比如用FileUtils.readFileToString这类方法,会直接把45MB的文件加载到内存,加上Java String的UTF-16存储特性,内存占用会翻倍,再加上解析后的对象,直接触发OOM。
  • 跳过不需要的字段:用reader.skipValue()跳过无关字段,减少对象创建和内存占用。
  • 及时释放资源:解析完立即关闭流,处理完的对象不要长期持有(比如不要加到全局集合,直接写入持久化存储)。
  • 避免依赖largeHeap:在AndroidManifest设置android:largeHeap="true"只是临时缓解,不同设备的largeHeap大小不一,还会掩盖内存问题,从解析方式优化才是根本。

为什么之前的方案失效?

大概率是因为方案仍在全量加载JSON(比如先转成String),或者没有真正用流式解析,而是一次性生成了整个对象集合,导致内存占用居高不下。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 15:48:30