在JAVA中,流式和基于树的XML解析器在开始时是否消耗了相似的内存量

在JAVA中,流式和基于树的XML解析器在开始时是否消耗了相似的内存量,java,xml,dom,xml-parsing,sax,Java,Xml,Dom,Xml Parsing,Sax,有两个主要的解析器来读取XML 流解析器-(例如:SAX、StAX) 基于树的解析器(例如:DOM、AXIOM等) 据说流式解析器比基于树的解析器使用更少的内存。需要注意的一点是,与基于树的解析器不同,流式解析器不提供整个XML树供开发人员导航。在那里,我们可以根据事件进行导航。在处理每个事件之后,处理器可以从内存中丢弃与该事件关联的数据(xml内容) 但是,在这两种情况下,我们都必须向解析器提供整个XML内容。因此,在内部,解析器必须将整个XML内容存储在内存中,以便在每个节点中导航。所以,我

有两个主要的解析器来读取XML

  • 流解析器-(例如:SAX、StAX)
  • 基于树的解析器(例如:DOM、AXIOM等)
  • 据说流式解析器比基于树的解析器使用更少的内存。需要注意的一点是,与基于树的解析器不同,流式解析器不提供整个XML树供开发人员导航。在那里,我们可以根据事件进行导航。在处理每个事件之后,处理器可以从内存中丢弃与该事件关联的数据(xml内容)

    但是,在这两种情况下,我们都必须向解析器提供整个XML内容。因此,在内部,解析器必须将整个XML内容存储在内存中,以便在每个节点中导航。所以,我的论点是,流式解析器如何比基于树的解析器消耗更少的内存

  • 当它开始读取XML时,流式解析器和基于树的解析器是否都消耗相似的内存量
  • 流式解析器使用哪些技术比基于树的解析器消耗更少的内存
  • SAX:

    斯塔克斯:

    公理:

        XMLStreamReader             parser                              = XMLInputFactory.newInstance().createXMLStreamReader(new StringBufferInputStream(responseXML));
        OMElement                   documentElement                     = new StAXOMBuilder(parser).getDocumentElement();
    
    参考资料:


    我认为您混淆了两个部分:

  • 开发人员如何向解析器提供XML
  • 解析器如何读取数据
  • 第一部分你有两个选择(实际上多于两个,但我们会考虑这两个最常见的)。
  • 您可以告诉解析器读取文件或套接字。在这种情况下,流解析器在内存中永远不会有XML的完整副本。但是,如果您将XML作为字符串加载到内存中,然后将其提供给解析器,那么消耗内存的是您,而不是解析器。它会尽职尽责地在字符串上“流”,而不会保留自己的XML内部副本
  • 对于DOM解析器,它确实构建了一个完整的内存树。在向其提供文件的情况下,实际文件内容在构建DOM结构后被丢弃。当您提供一个字符串时,在解析结束时,您将得到新构建的DOM树以及包含XML源的字符串

  • 如果不需要在随机方向上导航树,请使用流解析器。否则,您将不得不使用DOM。

    将DOM或JDOM这样的树构建库称为“解析器”已变得如此普遍,这相当令人遗憾。实际上,这里有两种软件:一种是解析器(它读取源代码中的字符序列,对其进行分析,并发出一系列表示语法单元(如开始和结束标记)的事件),另一种是树生成器,它从解析器获取事件序列并构建内存中的树

    因此,您不能选择两种不同类型的解析器。您的选择是让解析器直接将事件传递给应用程序,还是让它将事件传递给树生成器,然后将完成的树传递给应用程序


    解析器不使用大量内存。树生成器会这样做。但是树生成器以更易于处理的形式向应用程序提供信息。

    “在这两种情况下,我们都必须向解析器提供整个XML内容。”这是错误的假设。通常提供一个输入流,用于将XML读入SAX或StAX解析器。这些解析器不会将整个XML加载到内存中。他们将其流式传输。@Seelenvirtuose:但每次我们都将整个XML字符串提供给这些解析器。对吗?因此,该字符串必须在内存中才能在解析器中读取。Hmmm。。。我不完全明白“将整个XML字符串提供给每个解析器”的意思。你提到的三个教程都是关于文件而不是字符串的(我没有看youtube视频)。但是,是的,如果内存中已经有一个XML字符串,那么它将在内存中消耗其全部大小。但这在没有解析的情况下已经是真的了。“在这种情况下,流式解析器的内存中永远不会有XML的完整副本。但是,如果您将XML作为字符串加载到内存中,然后将其提供给解析器,则消耗内存的是您,而不是解析器。它会尽职尽责地在您的字符串上“流”,而不会保留自己的XML内部副本。”Jim说得很好。塔克斯。对我也觉得我错过了一些东西。再次感谢大家,,
        XMLInputFactory             inputFactory    = XMLInputFactory.newInstance();
        XMLEventReader              eventReader     = inputFactory.createXMLEventReader(new FileInputStream(configFile));
    
        XMLStreamReader             parser                              = XMLInputFactory.newInstance().createXMLStreamReader(new StringBufferInputStream(responseXML));
        OMElement                   documentElement                     = new StAXOMBuilder(parser).getDocumentElement();