没有过多内存分配的Java XML解析器

没有过多内存分配的Java XML解析器,java,xml,parsing,memory-management,Java,Xml,Parsing,Memory Management,在工作中,我使用DefaultHandler类解析大型XML文件。这样做,我注意到这个接口为元素名、属性名和值等分配了许多Strings 因此,我考虑创建一个XML解析器,它只执行绝对最小的对象分配。目前我需要: 一个StringBuilder,用于构建元素名称、属性名称等 一个字符集解码器,用于将字节转换为字符 我的用于解析的测试程序如下所示: import java.io.BufferedInputStream; import java.io.FileInputStream; impor

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

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

  • 一个StringBuilder,用于构建元素名称、属性名称等
  • 一个字符集解码器,用于将字节转换为字符
我的用于解析的测试程序如下所示:

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();
    }
  }
}
import java.io.BufferedInputStream;
导入java.io.FileInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.util.ArrayList;
导入java.util.LinkedHashMap;
导入java.util.List;
导入java.util.Map;
公共类XmlParserDemo{
公共静态void main(字符串[]args)引发IOException{
列出所有歌曲=新建ArrayList();
InputStream fis=新文件InputStream(“d:/song_info.xml”);
试一试{
XmlParser=newxmlparser(newbufferedInputStream(fis));
if(parser.element(“AllSongs”)){
while(parser.element(“Track”)){
Map track=newlinkedhashmap();
while(parser.element()){
String name=parser.getElementName();
字符串值=parser.text();
track.put(名称、值);
parser.endElement();
}
所有歌曲。添加(曲目);
parser.endElement();
}
parser.endElement();
}
}最后{
fis.close();
}
}
}
这段代码看起来比我用
XMLEventReader
进行的实验要好。现在唯一缺少的部分是上面代码中提到的
XmlParser
类。你知道以前有没有人写过这样的代码?这真的只是我的一个宠物项目,但我很好奇,旧的语句对象创建是昂贵的,它还有多少价值

是的,我知道
LinkedHashMap
s占用了大量内存。这实际上只是解析部分,我想提高内存效率。其他一切都只是为了制作一个简单的示例。

在Java中,“对象创建很昂贵”已经有很长一段时间没有实现了。分配通常非常便宜(移动指针),垃圾收集已经走过了漫长的道路

我肯定会使用一个XMLAPI,它可以让您轻松地做您想做的事情,而不是过多地担心过多的内存分配,除非您认为您会突破性能界限

我确信有一些XML API设计为具有特别小的内存占用——但是您的XML文件有多大?如果它们足够小,可以很容易地放入内存中,我就不用担心了。。。如果它们太大了,你真的需要考虑一个流式API。我怀疑一个特别高效的解析器可以在内存中容纳它,而“普通”解析器不能容纳它的大小范围在适用性方面相对较小。

在Java中,“对象创建是昂贵的”在相当长的一段时间内都不是真的。分配通常非常便宜(移动指针),垃圾收集已经走过了漫长的道路

我肯定会使用一个XMLAPI,它可以让您轻松地做您想做的事情,而不是过多地担心过多的内存分配,除非您认为您会突破性能界限


我确信有一些XML API设计为具有特别小的内存占用——但是您的XML文件有多大?如果它们足够小,可以很容易地放入内存中,我就不用担心了。。。如果它们太大了,你真的需要考虑一个流式API。我怀疑,在适用性方面,一个特别高效的解析器可以在内存中容纳它,而“普通”解析器却不能容纳它的大小范围相对较小。

您想要解决的问题是什么?性能差,解析器使用了太多内存,还是其他原因?如果是性能/内存使用,那么在花时间编写一个新的解析器之前,最好先对其进行分析,然后再预感到对象分配是昂贵的。我想看看我能在多大程度上避免内存分配。不是说我现在需要它,但也许以后,当我真的需要它的时候,我可以利用我在这里学到的东西。你想解决什么问题?性能差,解析器使用了太多内存,还是其他原因?如果是性能/内存使用,那么在花时间编写一个新的解析器之前,最好先对其进行分析,然后再预感到对象分配是昂贵的。我想看看我能在多大程度上避免内存分配。并不是说我现在需要它,但也许以后,当我真的需要它的时候,我可以利用我在这里学到的东西。你说服了我。我读了一篇关于StAX(at)的文章,并尝试了它,只要我不调用任何不必要的方法,它的内存效率是我想要的。你说服了我。我读了关于StAX(at)的文章,并尝试了它,只要我不调用任何不必要的方法,它的内存效率是我想要的。