扩展读取大型XML文件的应用程序

时间:2011-09-10 01:59:06

标签: java xml performance scalability

我有一个应用程序,它定期读取大量的XML文件(大约20-30个),比如每10分钟一次。现在每个XML文件的大小至少可以达到40-100 MB。一旦每个XML读取,就会从文件中创建一个映射,然后映射通过处理器链(10-15)传递,每个处理器使用数据,执行一些过滤或写入数据库等。

现在应用程序在32位JVM中运行。目前无意转移到64位JVM。预期的内存占用量非常高......接近32位JVM的阈值。现在,当我们收到大文件时,我们将生成的地图序列化为磁盘并同时运行处理器链最多3-4个映射,就好像我们试图同时处理所有映射一样,它很容易进入OutOfMemory。垃圾收集也很高。

我有一些想法,但想知道是否有一些人已经尝试/评估过的选项。那么有什么选择来扩展这种应用程序呢?

2 个答案:

答案 0 :(得分:2)

是的,为了鹦鹉@aaray和@MeBigFatGuy,你想为此使用一些基于事件的解析器,提到的dom4j,或SAX或StAX。

作为一个简单的例子,如果您批量加载,100MB XML消耗至少200MB的RAM,因为每个字符立即扩展为16位字符。

接下来,您未使用的任何元素标签将消耗额外的内存(加上所有其他行李和节点的簿记)并且全部浪费了。如果您正在处理数字,如果数字大于2位,将原始字符串转换为长字符将是净赢。

IF(这是一个BIG IF)你使用了很多相当小的字符串,你可以通过String.intern()来保存一些内存。这是一个规范化过程,它确保字符串已经存在于jvm中,它是共享的。这样做的缺点是它会污染你的permgen(一旦被拘禁,总是被拘禁)。 PermGen相当有限,但另一方面它对GC几乎免疫。

您是否考虑过能够通过外部XSLT运行XML以删除在您进入JVM之前不想处理的所有内容?有几个独立的命令行XSL处理器,您可以使用它们来预处理文件,使其更加清晰。这实际上取决于您实际使用的数据量。

通过使用基于事件的XML处理模型,XSLT步骤几乎是多余的。但是基于事件的模型基本上都很难使用,所以使用XSLT步骤可以让你重用一些现有的DOM逻辑(假设你正在做的事情)。

你的内部结构越平坦,它们在记忆方面就越便宜。实际上,运行32b vm有一点优势,因为实例指针的大小只有一半。但是,当你谈论1000个或数百万个节点时,这一切都会加速而且很快。

答案 1 :(得分:1)

您可以将每个XML文件的内容插入到临时数据库表中,每个链接链接都会获取所需的数据。您可能会失去性能,但会获得可扩展性。