1

我已经将 Jerkson 用于 scala,将我的对象列表序列化为 JSON 文件。我能够将对象分解为 JSON 格式对象并写入文件。现在,当我想将它读入我的程序以进行进一步处理时,我得到了这个错误。仅供参考,我的文件大小是 500MB,将来可能会增长到 1GB。

我看到很少有论坛要求增加XX:MaxPermSize=256M。我不确定这是否能解决我的问题,即使现在可以解决,但当我的 JSON 文件的大小增长到 1GB 时,有什么保证以后不会出现这种情况。有更好的选择吗?谢谢!

Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
    at java.lang.String.intern(Native Method)
    at org.codehaus.jackson.util.InternCache.intern(InternCache.java:41)
    at org.codehaus.jackson.sym.CharsToNameCanonicalizer.findSymbol(CharsToNameCanonicalizer.java:506)
    at org.codehaus.jackson.impl.ReaderBasedParser._parseFieldName(ReaderBasedParser.java:997)
    at org.codehaus.jackson.impl.ReaderBasedParser.nextToken(ReaderBasedParser.java:418)
    at com.codahale.jerkson.deser.ImmutableMapDeserializer.deserialize(ImmutableMapDeserializer.scala:32)
    at com.codahale.jerkson.deser.ImmutableMapDeserializer.deserialize(ImmutableMapDeserializer.scala:11)
    at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2704)
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1315)
    at com.codahale.jerkson.Parser$class.parse(Parser.scala:83)
    at com.codahale.jerkson.Json$.parse(Json.scala:6)
    at com.codahale.jerkson.Parser$class.parse(Parser.scala:14)
    at com.codahale.jerkson.Json$.parse(Json.scala:6)
4

2 回答 2

3

从堆栈跟踪中,我们可以看到 Jackson 实习生的字符串被解析为文档中的字段名称。当一个 String 被实习时,它会被放入 PermGen 中,这是您即将用完的堆的一部分。我认为这是因为您的文档有很多很多不同的字段名称 - 可能是使用某种命名方案生成的?无论如何,增加 MaxPermSize 可能会有所帮助,或者至少会延迟问题,但不会完全解决问题。

另一方面,在杰克逊禁用字符串实习应该完全解决它。Jackson 常见问题解答有更多关于调整哪些配置选项的信息: ​​http://wiki.fasterxml.com/JacksonFAQ#Problems_with_String_intern.28.29ing

于 2013-11-11T20:57:05.753 回答
1

增加记忆只会治标不治本。我会说这个 Jerkson 内存问题是因祸得福,它暴露了一个基本的设计缺陷。

至于您如何治愈这种疾病,我不能肯定地说,因为我对您的应用程序或用例一无所知。我很确定您一次不需要 1 GB 的信息。考虑将 JSON 文件的读取流式传输到数据库或缓存中,然后仅获取解决特定问题所需的内容。

含糊不清,我知道,但如果没有更多细节,我无法提供具体细节。底线是流式传输和持续存在。

于 2013-11-11T20:42:31.703 回答