0

问题 - 解析 XML 字符串时,我的程序中的内存利用率一直在增长。

我有一个在 TCP 端口上实时传输的 XML 流。
我使用 Netty 提取 xml 数据,然后使用 XStream 将 XML 字符串反序列化/解组为 Java 对象树。

当我使用 netbeans 配置文件监控内存消耗时,我看到 HEAP 随着时间的推移而增长,最后 JVM 抛出 OutOfMemory 异常。我跟踪了调用堆栈,并附上了我正在运行的一个测试的屏幕截图。

当我将 XML 字符串反序列化/解组为 Java 对象时,似乎正在发生内存消耗。

我在 XStream 中尝试了不同的解析器来进行解析——XPP3、KXML、STAX。我什至尝试过 JAXB 而不是 XStream 来解组。无论我使用什么解析器,问题仍然存在。

到目前为止,我已经尝试了所有这些不同的解析器,但我有同样的问题。

  xstream1 = new XStream(new KXml2Driver());
  xstream2 = new XStream(new StaxDriver());
  xstream3 = new XStream(new JDomDriver());
  xstream4 = new XStream(new Xpp3Driver());

就像我提到的那样,我什至尝试使用 JAXB 来解组而不是 XStream ......仍然是同样的问题。

如果您查看附加的图像,它的这个 Arrays.copyOfRange 调用就在显示的 char[] 正下方......无论它是哪个解析器,这个调用总是显示在跟踪的顶部。

我完全不知道如何解决或解决这个问题

请注意 - 我不是从文件中读取 XML。我得到一个包含小 XML 块的实时数据流。我提取每个块以将其转换为 Java 对象以进行进一步处理

谢谢 使用 Netbeans Profiler 从内存消耗数据中提取的分配堆栈跟踪

4

2 回答 2

1

好吧,根据您向我们展示的证据,最简单的解释是您的 JVM 堆太小。尝试按照该命令的手册条目中的说明添加“-Xmx”选项。java

如果这不起作用,那么您需要更深入地了解您的应用程序正在做什么:

  • 这些“小”XML 块的大小是否有上限?你能得到一个比你允许的更大的块吗?

  • 您的应用程序的处理是否将每个块中的内容保存在一个长期存在的内存数据结构中?你可以为该数据结构的大小设置一个上限吗?也许通过扔东西?(或者通过使用“弱引用”以便 GC 将它们丢弃?)

  • 您的应用程序是否泄漏内存?

于 2012-07-08T01:03:20.770 回答
1

上面的答案是可靠的。我只想补充一点,内存中的对象图可能很昂贵。如果我理解您的描述,您有一个包含许多小 XML 块的 XML 流?SAX 解析以及管道方法可能是您的答案。当 SAX 解析器找到每个工作块时,它会将其传递给下游进程,而无需将所有对象拉入内存。

于 2012-07-08T06:21:53.310 回答