Java 在SAX解析器中解析大型XML文件时出现无内存异常

Java 在SAX解析器中解析大型XML文件时出现无内存异常,java,xml,parsing,Java,Xml,Parsing,我读过一些关于使用SAX解析器解析java中的XML文件优于使用DOM的文章。 我最感兴趣的一点(如前所述)是 Sax适用于大型XML文件,Sax解析器不会将XML文件作为一个整体加载到内存中 但是现在,我已经编写了一个解析器,使用SAX从XML文件中派生出实体,用于一个几乎1.4GB的大文件,它生成了以下异常 org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; The parser has encountered mor

我读过一些关于使用SAX解析器解析java中的XML文件优于使用DOM的文章。 我最感兴趣的一点(如前所述)是

Sax适用于大型XML文件,Sax解析器不会将XML文件作为一个整体加载到内存中

但是现在,我已经编写了一个解析器,使用SAX从XML文件中派生出实体,用于一个几乎1.4GB的大文件,它生成了以下异常

org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; The parser has encountered more than "64,000" entity expansions in this document; this is the limit imposed by the application.
如果整个文件没有加载到内存中,内存会有什么问题


如何解决此问题?

使用JVM参数更改实体扩展限制:

-DentityExpansionLimit=1000000

您还可以考虑使用StAX

SAX是事件驱动和串行的。它可以处理大型XML,但需要大量CPU资源

DOM将完整的文档保存在内存中

StAX是一种较新的API。它通过XML进行流式传输。可以将其视为文档上的光标或迭代器。它的优点是可以跳过不需要的元素(属性、标记等)。如果使用得当,它占用的CPU资源要少得多

使用SAX,XML推送事件


使用StAX,您可以将XML拉到您的面前。

这不一定是实际的内存限制,而是针对DOS攻击的一种保护措施,如。如果您的输入XML合法地包含那么多实体,您可以在解析器中增加该限制。看看它的文档。你建议我用这个保护措施做什么?我想我说过了。我应该看看JVM的文档吗?取决于你如何运行你的程序。这是一个命令行参数。这篇文章包含了我的解析器代码,希望你理解我是如何处理它的是的,但是你是如何运行它的。您是否在命令提示符下键入java blah blah?您是否通过IDE执行它?在“参数”选项卡上的“运行配置”下,它被称为“VM参数”。这就是你想补充的地方。非常感谢你,真的很有效。:)我真的非常感谢你。这是否意味着我所有创建一个解析器(使用SAX)的努力都白费了?如果你已经解决了问题,你可以继续使用SAX。我只是想告诉你还有另一种解析XML的现代方法。另一个优点是:使用SAX u只能解析XML,而使用StAX u也可以编写XML。如果您使用精心选择的方法编写了SAX实现,也许您可以重用大量代码,并尝试使用StAX方法来衡量性能的差异。相信我,你会感到惊讶的:当正确使用并跳过不必要的元素时,你的解析时间会大大减少!在下面对答案的评论中,我为我的代码添加了一个链接。你看,这只是一个提议!如果你愿意,我可以给你一个StAX片段。它通常用于特定的模式。我将查找它,并用一个小例子编辑我的帖子。