将DOM XML解析器用于大型XML文档以进行多个查找操作的替代方法是什么?

时间:2012-03-13 04:04:36

标签: java xml parsing dom memory

我正在存储用于在XML文档中排名用户的数据 - 每个用户一行 - 包含36个字符键,得分,排名和用户名作为属性。

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE Ranks [<!ELEMENT Rank ANY ><!ATTLIST Rank id ID #IMPLIED>]>
<Ranks>
..<Rank id="<userKey>" score="36.0" name="John Doe" rank=15></Rank>..
</Ranks>

有几个这样的文档可以使用DOM解析器根据请求进行解析,并保存在内存中,直到文件更新为止。这发生在支持小部件的HttpServlet中。每次加载窗口小部件时,它都会使用get请求调用servlet,然后需要查询其中一个文档。对文档的查询需要以下操作:

  • 查找 - 查找特定ID
  • 遍历每个Rank元素并获取id属性

在我的测试环境中,用户数量<100,一切正常。但是我们很快就会投放到拥有200,000+用户的系统。我对我的方法的可扩展性有严重的担忧 - 即OutOfMemoryException!

我一直坚持实现平衡性能和内存使用的想法。虽然DOM很适合查找操作,但由于它的大小,它可能会窒息。我对StAX了解不多,但从我所看到的内容看来它似乎可以解决内存问题,但可能真的会减慢查询速度,因为我必须有效地遍历文档才能找到感兴趣的元素(是的正确?)。

问题:

  • 是否可以使用StAX对大型文档进行多次查找(如getElementById)操作,以便足够快地为HttpRequest提供服务?
  • DOM Parser可以处理的最大文件大小是多少?
  • 是否可以估算每个用户使用上述结构的XML文档的内存量?

由于

编辑:我不允许使用数据库。

编辑:使用自定义格式的文件代替并使用正则表达式在文件中搜索所需的条目会更好/更整洁吗?

3 个答案:

答案 0 :(得分:2)

听起来您正在使用xml文档作为数据库。我认为使用适当的数据库,并根据需要导入/导出到xml会更快乐。有几个数据库工作得很好,所以你也可以使用一个得到很好支持的数据库,比如mysql或postgresql,尽管sqlite比xml更好。

就SAX解析而言,您基本上构建了一个大型状态机,用于处理解析时发生的各种事件(输入标记,留下标记,查看数据等)。然后,您可以自己管理内存(根据您所处的状态记录您看到的数据),因此您可以拥有更好的内存占用,但是为每个Web请求运行类似的查询是荒谬的,特别是当你可以将所有数据存储在一个漂亮的索引数据库中时。

答案 1 :(得分:2)

这里的一个大问题是DOM不是线程安全的,所以即使是读操作也需要同步。从这个角度来看,使用JDOM或XOM肯定会更好。

另一个问题是用于查找数据的搜索策略。您确实希望通过索引而不是使用串行搜索来支持查询。实际上,您需要一个不错的查询优化器来生成有效的访问路径。因此,考虑到您不使用数据库的限制,这听起来就像内存中的XQuery引擎具有激进的优化,其中明显的候选者是Saxon-EE。但后来我会说,不是吗?

答案 2 :(得分:0)

对于繁重的XML处理,VTD-XML是最有效的选项,它比JDOM,DOM4j或DOM更有效......关键是其信息集建模的非面向对象方法......它也不太可能导致内存不足异常...阅读2013年的论文,了解各种XML框架之间的综合比较/基准

Processing XML with Java – A Performance Benchmark