2015-04-27 49 views
0

我有一个大对象我想解析为json Jackson-mapper。 它工作正常,直到对象变得太大。使用杰克逊映射器解析为json导致

我在mac上使用intellij。

代码:

private String serializeToJson(T item) { 
    String json; 
    ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); 
    try { 
     json = ow.writeValueAsString(item); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     json = ""; 
    } 
    return json; 
} 

错误:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
:BL_generate FAILED 

BUILD FAILED 

Total time: 12 mins 14.491 secs 
    at java.util.Arrays.copyOfRange(Arrays.java:3664) 
    at java.lang.String.<init>(String.java:201) 
    at java.lang.StringBuilder.toString(StringBuilder.java:407) 
    at org.codehaus.jackson.util.TextBuffer.contentsAsString(TextBuffer.java:362) 
    at org.codehaus.jackson.io.SegmentedStringWriter.getAndClear(SegmentedStringWriter.java:100) 
    at org.codehaus.jackson.map.ObjectWriter.writeValueAsString(ObjectWriter.java:394) 
    at com.waze.routing.automation.io.string.JsonFileHandler.serializeToJson(JsonFileHandler.java:81) 

I'm not sure how to split an object or to write it in parts (append to existing file) 

我试图扩大堆空间,但它并没有帮助

task BL_generate(type: JavaExec) { 
    jvmArgs = ["-Xms1024m","-Xmx1024m"] 
    classpath sourceSets.main.runtimeClasspath 
    main = "com.m.BaselineGeneratorRunner" 
} 

我看了几个帖子:post1post2

但我不知道如何使用它在我的情况。流媒体如何帮助我处理一个大对象? (不是数组)。

+0

为什么你使用旧版本的杰克逊? 'org.codehaus.jackson'移至最新版本并再次检查。 – igreen

+0

什么是最新版本的命名空间? –

+0

[search maven](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.fasterxml.jackson.core%22) – igreen

回答

1

这里的主要问题是为什么你想要一个java.lang.String在这里?通常你宁愿将内容写入流或文件。

如果您真的希望将整个JSON序列化为String - String对象占用大量内存,那么流式处理将无法帮助您;至少是File的2倍。

实际上它不止一点:在构造字符串的时候,缓冲版本(在char[] sergments中)占用了很多空间,所以它大约是等效文件的4倍。 你的堆也分为不同的区域(年轻的,老一代),所以我猜想在最坏的情况下,你可能需要大约10倍的内存。 如果是这样,1024 megs的设置应该可以让你处理约100兆字节的JSON内容。

我会试图找出如何避免必须先创建一个大的字符串,然后问题应该是可以解决的。

+0

我不知道我理解“json streaming”的含义。它如何经济? –

+0

JSON流从根本上意味着增量读取/写入令牌,一次一个,而不一定一次读取整个文档(或者在写入任何内容之前必须在内存中构建全部内容)。如果可以做到这一点(例如,只是在给定的时间读取内容的子集),它可以帮助很多内存使用情况。所有杰克逊解析/生成都使用底层流式解析器/生成器,这可能会造成一些混淆;即使在高层次使用不是增量/流媒体。 – StaxMan