Java XML 解析器无需过多内存分配

标签 java xml parsing memory-management

在工作中,我使用 DefaultHandler 类解析大型 XML 文件。这样做时,我注意到这个接口(interface)为元素名称、属性名称和值等分配了许多 String

由此,我考虑创建一个只执行绝对最少对象分配的 XML 解析器。目前我需要:

  • 一个 StringBuilder 用于构建元素名称、属性名称等。
  • 一个 CharsetDecoder,用于将字节转换为字符。

我的测试程序,用于解析http://magnatune.com/info/song_info.xml ,看起来像这样:

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class XmlParserDemo {
  public static void main(String[] args) throws IOException {
    List<Map<String, String>> allSongs = new ArrayList<Map<String, String>>();

    InputStream fis = new FileInputStream("d:/song_info.xml");
    try {
      XmlParser parser = new XmlParser(new BufferedInputStream(fis));
      if (parser.element("AllSongs")) {
        while (parser.element("Track")) {
          Map<String, String> track = new LinkedHashMap<String, String>();
          while (parser.element()) {
            String name = parser.getElementName();
            String value = parser.text();
            track.put(name, value);
            parser.endElement();
          }
          allSongs.add(track);
          parser.endElement();
        }
        parser.endElement();
      }
    } finally {
      fis.close();
    }
  }
}

此代码看起来比我使用 XMLEventReader 进行的实验要好。现在唯一缺少的部分是上面代码中提到的 XmlParser 类。您知道以前是否有人编写过该代码吗?这实际上只是我的一个宠物项目,但我很好奇“对象创建很昂贵”这一旧说法现在还有多少值(value)。

是的,我知道LinkedHashMap正在使用大量内存。我实际上只是想提高内存效率的解析部分。其他一切只是为了做一个简单的例子。

最佳答案

“对象创建成本高昂”在 Java 中很长一段时间以来都不是事实。分配通常非常便宜(移动指针),并且垃圾收集已经取得了长足的进步。

肯定使用 XML API,它可以让您轻松地做您想做的事情,而不必过多担心过多的内存分配,除非您认为您将突破性能极限。

我确信有 XML API 被设计为具有特别小的内存占用 - 但您的 XML 文件到底有多大?如果它们足够小,可以轻松装入内存,我就不会担心……如果它们太大,您确实需要考虑使用流式 API。我怀疑,就适用性而言,特别高效的解析器可以将其放入内存但“普通”解析器不能放入的大小范围相对较小。

关于Java XML 解析器无需过多内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3250921/

相关文章:

xml - 查找单个字符串的每个实例并将其替换为列表或文件中的另一个实例

PHP 词法分析器和解析器生成器?

java - 如何获取图像(在文件中)的 channel 数(颜色深度)?

java - Jprofiler 无法让代理工作

java - 从 MusicBrainz Web 服务检索元数据

json - 使用 XSLT 创建 JSON 输出单引号转换(XML 到 JSON)

c# - 从c#中的linux "ps"命令输出解析进程启动时间

for-loop - for 循环括号内的两个分号

java - 如何从 BufferedImage 的 java 中的 R、G、B 值获取 rgb 像素值

Java - Uber jar (Maven Shaded) 无法将资源视为 URL