【问题标题】:java.lang.OutOfMemoryError: Java heap space when try to convert Java Object to Json Stringjava.lang.OutOfMemoryError:尝试将 Java 对象转换为 Json 字符串时的 Java 堆空间
【发布时间】:2013-11-24 13:05:58
【问题描述】:

我尝试将 csv 文件转换为 200K 对象的 Json 文件,其中对象代表 csv 中的 1 行。

我在 32 位和项目配置 VM 参数上安装了 Java:-Xmx1024m

但是我得到:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Unknown Source)
    at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
    at java.lang.AbstractStringBuilder.append(Unknown Source)
    at java.lang.StringBuffer.append(Unknown Source)
    at java.io.StringWriter.write(Unknown Source)
    at com.google.gson.stream.JsonWriter.string(JsonWriter.java:478)
    at com.google.gson.stream.JsonWriter.value(JsonWriter.java:328)
    at com.google.gson.Streams.write(Streams.java:113)
    at com.google.gson.Streams.write(Streams.java:136)
    at com.google.gson.Streams.write(Streams.java:136)
    at com.google.gson.Streams.write(Streams.java:124)
    at com.google.gson.Streams.write(Streams.java:136)
    at com.google.gson.Gson.toJson(Gson.java:362)
    at com.google.gson.Gson.toJson(Gson.java:346)
    at com.google.gson.Gson.toJson(Gson.java:260)
    at com.google.gson.Gson.toJson(Gson.java:240)
    at ConvertFromCsv2JsonTWC.init(ConvertFromCsv2JsonTWC.java:186)
    at ConvertFromCsv2JsonTWC.main(ConvertFromCsv2JsonTWC.java:48)

在行中:

Gson gson = new Gson();

String output = gson.toJson(container);// <---- crash

对于 50k 行,它工作正常。

这是我构建的Json模板:

{
    "crs": {
        "type": "none"
    },
    "type": "FeatureCollection",
    "features": [{
        "geometry": {
            "type": "Point"
        },
        "properties": {
            "ap mac": "00:11:22:33:44:55",
            "ssid": "WiFi",
            "lat": "35.111111",
            "long": "-118.11111",
            "address": "370 xxxxxx",
            "city": "xxxxxxx",
            "state": "CA",
            "zip code": "11111",
            "country": "US",
            "business n": "",
            "location c": "Health Club/Gym",
            "location q": "",
            "indoor fla": "yes"
        },
        "point": [35.390284,
        -118.9929],
        "id": 0,
        "type": "Feature"
    },
          {...},
          ... 
          200000...

所以我在properties 列表中有 200K 个对象

解决方法是创建单独的文件,每个文件 20k,但这不是好方法。

我该如何解决这个问题?

谢谢,

【问题讨论】:

  • 你能用stream 代替吗?这是很多数据。
  • @ElliottFrisch 请发布此评论作为答案,让我接受。谢谢

标签: java gson


【解决方案1】:

我建议您使用streaming,而不是尝试将其全部复制到String

【讨论】:

  • 如果只有具有不同属性的对象并且还有一千万条记录的列表,我该如何流式传输它??
【解决方案2】:

您可以使用Gson streaming API 代替遍历(流式传输)数据,而不是尝试一次全部加载。

【讨论】:

    【解决方案3】:

    数据太多,无法一次读取所有数据并将其保存在内存中。您应该将其分解为更小的部分并逐段处理。

    【讨论】:

      【解决方案4】:

      这就是你如何使用Gson Streaming API将数据作为字符串流式传输到Json中

      @Nullable
      public static String streamContainersIntoJsonString(List<Container> containers) {
          try {
              Gson gson = new Gson();
              ByteArrayOutputStream out = new ByteArrayOutputStream();
              JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, "UTF-8"));
              writer.setIndent("  ");
              writer.beginArray();
              for (Container container : containers) {
                  gson.toJson(container, Container.class, writer);
              }
              writer.endArray();
              writer.close();
      
              return out.toString("UTF-8");
          } catch (IOException e) {
              e.printStackTrace();
          }
      
          return null;
      }
      

      【讨论】:

      • 大列表内存不足异常
      猜你喜欢
      • 1970-01-01
      • 2011-08-30
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-24
      • 2021-09-18
      相关资源
      最近更新 更多