2012-02-21 50 views
2

我正在使用傑克遜1.9。在我的web應用程序中,我需要將複雜對象(如Spring的ModelMap,BindingResult,java.uil.Map)轉換爲JSON String對象。使用傑克遜1.9時的OutOfMemory

請考慮下面的代碼片段,我在嘗試這樣的一個轉換:

Map<String, Object> methodArgsMap = new HashMap<String, Object>(); 

methodArgsMap.put("map", map);/*map is an instance of org.springframework.ui.ModelMap*/ 

methodArgsMap.put("command", command);/*command is an instance of a custom POJO  viz.ReportBeanParam*/ 
methodArgsMap.put("result", result);/*result is an instance of org.springframework.validation.BindingResult*/ 

的方法是JSONProcessUtil。爲實現getObjectsAsJSONString(...)如下:

public final class JSONProcessUtil { 

private static ObjectMapper objectMapper; 

     static { 
       objectMapper = new ObjectMapper(); 
/*Start : Configs. suggested by Jackson docs to avoid OutOfMemoryError*/ 
       SerializationConfig serConfig = objectMapper.getSerializationConfig(); 
       serConfig.disable(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS); 

       objectMapper.getJsonFactory().configure(
           JsonParser.Feature.INTERN_FIELD_NAMES, false); 
       objectMapper.getJsonFactory().configure(
           JsonParser.Feature.CANONICALIZE_FIELD_NAMES, false); 
/*End : Configs. suggested by Jackson docs to avoid OutOfMemoryError*/ 

     } 


public static Map<String, String> getObjectsAsJSONString(
         Map<String, Object> argsMap) throws JsonGenerationException, 
         JsonMappingException, IOException { 

       log.info("Source app.In JSONProcessUtil.getObjectsAsJSONString(...)"); 

       Map<String, String> jsonStrMap = null; 

       if (!(argsMap == null || argsMap.isEmpty())) { 
         jsonStrMap = new HashMap<String, String>(); 

         Set<String> keySet = argsMap.keySet(); 
         Iterator<String> iter = keySet.iterator(); 
         String argName = null; 

         while (iter.hasNext()) { 

           argName = iter.next(); 

           log.info("Source app. argName = {}, arg = {} ", argName, 
               argsMap.get(argName)); 

           jsonStrMap.put(argName, 
               objectMapper.writeValueAsString(argsMap.get(argName)));/*The line giving error*/ 

           log.info("Proceeding to the next arg !"); 
         } 
       } 

       log.info("Source app. Exit from JSONProcessUtil.getObjectsAsJSONString(...)"); 

       return jsonStrMap; 
     } 
} 

我正在一個的OutOfMemoryError如下:

INFO [http-8080-7] (JSONProcessUtil.java:73) - Source app. argName = result, arg = org.springframework.validation.BeanPropertyBindingResult: 0 errors DEBUG [http-8080-7] (SecurityContextPersistenceFilter.java:89) - SecurityContextHolder now cleared, as request processing completed Feb 20, 2012 5:03:30 PM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet saas threw exception 
java.lang.OutOfMemoryError: Java heap space 
     at org.codehaus.jackson.util.TextBuffer._charArray(TextBuffer.java:  
674) 
     at org.codehaus.jackson.util.TextBuffer.expand(TextBuffer.java:633) 
     at org.codehaus.jackson.util.TextBuffer.append(TextBuffer.java:438) 
     at org.codehaus.jackson.io.SegmentedStringWriter.write(SegmentedStringWriter.java:69) 
     at org.codehaus.jackson.impl.WriterBasedGenerator._flushBuffer(WriterBasedGenerator.java:1810) 
     at org.codehaus.jackson.impl.WriterBasedGenerator._writeFieldName(WriterBasedGenerator.java:345) 
     at org.codehaus.jackson.impl.WriterBasedGenerator.writeFieldName(WriterBasedGenerator.java:217) 
     at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:426) 
     at org.codehaus.jackson.map.ser.BeanSerializer.serializeFields(BeanSerializer.java:175) 
     at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:142) 
     at org.codehaus.jackson.map.ser.impl.ObjectArraySerializer.serializeContents(ObjectArraySerializer.java:121) 
     at org.codehaus.jackson.map.ser.impl.ObjectArraySerializer.serializeContents(ObjectArraySerializer.java:28) 
     at org.codehaus.jackson.map.ser.ArraySerializers$AsArraySerializer.serialize(ArraySerializers.java:56) 
     at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:428) 
     at org.codehaus.jackson.map.ser.BeanSerializer.serializeFields(BeanSerializer.java:175) 
     at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:142) 
     at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:428) 
     at org.codehaus.jackson.map.ser.BeanSerializer.serializeFields(BeanSerializer.java:175) 
     at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:142) 
     at org.codehaus.jackson.map.ser.MapSerializer.serializeFields(MapSerializer.java:287) 
     at org.codehaus.jackson.map.ser.MapSerializer.serialize(MapSerializer.java:212) 
     at org.codehaus.jackson.map.ser.MapSerializer.serialize(MapSerializer.java:23) 
     at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:428) 
     at org.codehaus.jackson.map.ser.BeanSerializer.serializeFields(BeanSerializer.java:175) 
     at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:142) 
     at org.codehaus.jackson.map.ser.MapSerializer.serializeFields(MapSerializer.java:287) 
     at org.codehaus.jackson.map.ser.MapSerializer.serialize(MapSerializer.java:212) 
     at org.codehaus.jackson.map.ser.MapSerializer.serialize(MapSerializer.java:23) 
     at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:428) 
     at org.codehaus.jackson.map.ser.BeanSerializer.serializeFields(BeanSerializer.java:175) 
     at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:142) 
     at org.codehaus.jackson.map.ser.MapSerializer.serializeFields(MapSerializer.java:287) 

請指導有關解決相同。

感謝和問候!

回答

1

聽起來就像你正在產生一個巨大的JSON輸出,它被緩存在內存中。 這基於錯誤消息。

您的選擇要麼是:

  • 使用流輸出,以避免內存(但是,我不知道,如果Spring允許你這樣做),或
  • 增加堆大小,以便你有緩衝它內存不足

禁用內聯和規範化的功能只與解析有關,並且您正在生成JSON而不是解析。