使用 Jackson 1.9 时出现内存不足

发布于 2025-01-07 20:46:15 字数 6467 浏览 3 评论 0原文

我正在使用杰克逊 1.9。在我的 Web 应用程序中,我需要将复杂的对象(例如 Spring 的 ModelMap、BindingResult、java.uil.Map)转换为 JSON String 对象。

请考虑以下代码片段,我正在尝试进行此类转换:

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)

请指导如何解决该问题。

谢谢和问候!

I am using Jackson 1.9. in my web application wherein I require to convert complex objects e.g Spring’s ModelMap, BindingResult, java.uil.Map to JSON String objects.

Please consider the following code snippet where I am attempting one such conversion:

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*/

The method is JSONProcessUtil. getObjectsAsJSONString(...) implemented as follows :

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;
        }
}

I am getting an OutOfMemoryError as follows :

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)

Please guide about resolving the same.

Thanks and regards !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

絕版丫頭 2025-01-14 20:46:16

听起来您正在生成一个巨大的 JSON 输出,该输出会缓冲在内存中。
这基于错误消息。

您的选择是:

  • 使用流输出以避免在内存中缓冲它(但是,我不确定 Spring 是否允许您这样做),或者
  • 增加堆大小,以便您有足够的内存

禁用驻留和规范化的功能仅与解析相关,并且您正在生成 JSON,而不是解析。

Sounds like you are producing a huge JSON output, which gets buffered in memory.
This based on error message.

Your choices are either:

  • Use streaming output to avoid buffering it in memory (however, I am not sure if Spring allows you to do this), or
  • Increase heap size so you have enough memory

Features to disable interning and canonicalization are only relevant for parsing, and you are generating JSON, not parsing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文