2017-04-27 211 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也不是那麼容易。

相關問題