2017-04-27 210 views
0

我有一个需要序列化为Json字符串的大型Java对象(100MB +)。我用的是杰克逊的Json,直到我发现了它的大对象达到内存限制:将大型Java对象序列化为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对象的任何建议?我发现杰克逊图书馆可以做流式传输,但许多职位都提到了另一种方式,即将json字符串反序列化为对象。此外,似乎杰克逊lib比其他软件包,如gson,我没有亲自尝试过更好的性能。

谢谢。

+0

你想在什么情况下将* 100MB + *的数据传输到另一个系统? –

+1

在大型分布式系统中。 – Shiyu

+2

检查这个http://stackoverflow.com/questions/31477711/streaming-json-directly-to-response-with-jackson –

回答

0

This answer包含使用Jackson Streaming API的有用提示。一些更多的谷歌搜索显示有用的examples herehere

对于内存的消耗,我创建了一个简单的程序,产生了〜33MB的内存对象,并将这里的粗略估计:

  • 的问题使用标准的JSON的转换,它采用多达〜150MB内存
  • 使用杰克逊流API,它使用了高达60MB〜

不过,我确实需要手动创建JsonGenerator,这是高度依赖于对象的结构和它的不可扩展;对于复杂的对象,创建JsonGenerator也不是那么容易。

相关问题