没有过多内存分配的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)的文章,并尝试了它,只要我不调用任何不必要的方法,它的内存效率是我想要的。