代码之家  ›  专栏  ›  技术社区  ›  Roland Illig

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

  •  1
  • Roland Illig  · 技术社区  · 15 年前

    在工作中,我使用 DefaultHandler 班级。这样做时,我注意到这个接口分配了许多 String s,用于元素名、属性名和值等。

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

    • 一个用于构建元素名、属性名等的StringBuilder。
    • 一个字符集解码器,用于将字节转换为字符。

    我的测试程序,用于分析 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 上面代码中提到的类。你知道以前有人写过这段代码吗?这真的只是我的一个小项目,但我很好奇以前的说法 对象创建成本高昂 是值得的。

    是的,我知道 LinkedHashMap S占用了大量内存。我想提高内存效率的真正原因是解析部分。其他的一切只是为了做一个简单的例子。

    1 回复  |  直到 15 年前
        1
  •  1
  •   Jon Skeet    15 年前

    在Java中很长一段时间内,“对象创建是昂贵的”并不是真的。分配通常非常便宜(移动一个指针),垃圾收集也有很长的路要走。

    我愿意 一定地 使用一个XML API,它可以让您轻松地做您想要做的事情,而不是担心过多的内存分配,除非您认为您将推高性能界限。

    我肯定那里。 XML API的设计目的是具有特别小的内存占用—但您的XML文件到底有多大?如果它们足够小,可以很容易地融入记忆,我就不用担心了…如果它们太大,那么无论如何,您真的需要考虑流式API。我怀疑一个特别有效的解析器可以在内存中容纳它,但在适用性方面,“普通”解析器不能相对较小。