将大型Java对象序列化为Json Strings

时间:2017-04-27 04:47:10

标签: java json memory serialization out-of-memory

我有一个需要序列化为Json字符串的大型Java对象(100MB +)。我正在使用杰克逊Json,直到我发现它达到大对象的内存限制:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOfRange(Arrays.java:3664)
    at java.lang.String.<init>(String.java:207)
    at java.lang.StringBuilder.toString(StringBuilder.java:407)
    at com.fasterxml.jackson.core.util.TextBuffer.contentsAsString(TextBuffer.java:349)
    at com.fasterxml.jackson.core.io.SegmentedStringWriter.getAndClear(SegmentedStringWriter.java:83)
    at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:682)
    at JavaTest.objToJson(JavaTest.java:76)

执行转换的方法如下所示:

public static String objToJson(Object obj) {

    ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
    String json = null;

    try {
        json = ow.writeValueAsString(obj);
    } catch (JsonProcessingException e) {
        System.out.println("Error in objToJson(): " + e);
        e.getMessage();
        e.printStackTrace();
    }
    return json;
}

环境紧张,因此我无法随意增加堆大小。

有关更多内存有效的序列化Java对象方法的建议吗?我发现jackson库可以做流媒体,但很多帖子都说过相反的方法,即将json字符串反序列化为对象。此外,似乎jackson lib比其他软件包(如gson)具有更好的性能,我还没有尝试过。

感谢。

1 个答案:

答案 0 :(得分:0)

This answer包含使用Jackson Streaming API的有用提示。更多Google搜索会显示有用的examples herehere

对于内存消耗,我创建了一个简单的程序,在内存对象中生成~33MB,这是粗略估计:

  • 在问题中使用标准的json转换,它使用最多~150MB的内存
  • 使用jackson流API,最多使用~60MB

但是,我确实需要手动创建JsonGenerator,它高度依赖于对象结构,并且不可扩展;对于复杂的对象,创建JsonGenerator并不容易。