基于流和基于树的XML解析器在JAVA开始时消耗相似数量的内存

时间:2014-09-28 06:37:05

标签: java xml dom xml-parsing sax

有两种主要的解析器可以读取XML。

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

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

    1. 当它开始读取XML时,Streaming和基于树的解析器是否会占用相似数量的内存?
    2. Streaming解析器使用哪些技术比基于树的解析器消耗更少的内存?
    3. SAX:

      SAXParserFactory        factory     =   SAXParserFactory.newInstance();
      SAXParser               saxPaser    =   factory.newSAXParser();
      
      ResultHandler           handler     =   new ResultHandler();
      
      InputSource             input       =   new InputSource(new StringReader(xml));             
      input.setEncoding("utf-8");
      saxPaser.parse(input,handler);
      

      StAX的:

          XMLInputFactory             inputFactory    = XMLInputFactory.newInstance();
          XMLEventReader              eventReader     = inputFactory.createXMLEventReader(new FileInputStream(configFile));
      

      AXIOM:

          XMLStreamReader             parser                              = XMLInputFactory.newInstance().createXMLStreamReader(new StringBufferInputStream(responseXML));
          OMElement                   documentElement                     = new StAXOMBuilder(parser).getDocumentElement();
      

      参考文献:

2 个答案:

答案 0 :(得分:2)

我相信你混淆了两个部分:

  1. 开发人员如何向解析器提供XML
  2. 解析器如何读取数据
  3. 对于第一部分,你有两个选择(实际上超过两个,但我们会考虑最常见的两个)。

    1. 您可以告诉解析器从文件或套接字读取。在这种情况下,流式解析器永远不会在内存中拥有XML的完整副本。但是,如果您将XML作为String加载到内存中,然后将其提供给解析器,则使用内存而不是解析器的是您。它将尽职地“流式传输”您的字符串,而不是保留自己的XML内部副本。
    2. 对于DOM解析器,它确实构建了一个完整的内存树。在为其提供文件的情况下,在构建DOM结构后将丢弃实际的文件内容。当您提供String时,在解析结束时您将拥有新构建的DOM树PLUS包含XML源的String。
    3. 如果您不需要以随机方向导航树,请使用流解析器。否则你将不得不使用DOM。

答案 1 :(得分:1)

令人遗憾的是,将DOM或JDOM等树构建库作为"解析器"已经变得如此普遍。实际上这里有两个软件:一个解析器(它读取源代码中的字符序列,分析它,并发出一系列表示语法单元的事件,如开始和结束标记),以及一个树构建器,它接受来自解析器的事件序列并构建内存中的树。

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

解析器不使用大量内存。树构建器确实如此。但树构建器以更容易处理的形式向应用程序提供信息。