我有一个应用程序,它使用XmlUnit来获取来自两个XML文件的差异。但问题是XmlUnit使用JDOM。我的xml文件是~1GB大!
在JDOM文档中存储这些xml需要太多的RAM。
我试过使用SlimJDOMFactory,但仍然使用太多内存!!
实际上,我需要在XML文件中向前和向后导航。没有JDOM,我就找不到简单的方法。
有人能帮忙吗?
下面是关于如何构建JDOM文档的代码示例:
private org.jdom2.Document refDocJdom2;
private org.jdom2.Document resDocJdom2;
SAXBuilder sxb = new SAXBuilder();
sxb.setJDOMFactory(new SlimJDOMFactory());
popmsg("Validating reference file...");
try {
refDocJdom2 = sxb.build(referenceXML_Path);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error while parsing Reference : "+referenceXML_Path+" file.\nCheck XML file validity.");
return;
}
popmsg("Reference file validated");
popmsg("Validating result file....");
try {
resDocJdom2 = sxb.build(resultXML_Path);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error while parsing result "+resultXML_Path+" file.\nCheck XML file validity.");
return;
}
popmsg("Result file validated");
popmsg("Validation Done.");
getDifferencies(referenceXML_Path, resultXML_Path);
d2 = new Date();
}
public void getDifferencies(String fileRef, String fileRes) throws SAXException, IOException {
popmsg("Documents : VALID XML format");
popmsg("Shearching for differencies....");
Reader refReader;
refReader = new FileReader(fileRef);
Reader resReader = new FileReader(fileRes);
Diff aDifference = new Diff(refReader, resReader);
if(refReader != null){
refReader.close();
}
refReader = null;
if(resReader != null){
resReader.close();
}
resReader = null;
//TODO
// XMLUnit.setIgnoreWhitespace(true);
myDetailledDiff = new DetailedDiff(aDifference);
myDetailledDiff.overrideDifferenceListener(new IgnoreNamedElementsDifferenceListener());
myDetailledDiff.overrideElementQualifier(new ElementNameAndAttributeQualifier());
allDiffs = myDetailledDiff.getAllDifferences();
myDetailledDiff = null;
popmsg("Got all differencies...\nGoing to Sort them now...");
popmsg("Diff SIZE : "+allDiffs.size());
myDiffsList = new ArrayList<MyDifference>(allDiffs.size());
if(allDiffs.size() > 0){
Difference aDiff;
for (int i = 0; i < allDiffs.size(); i++){
aDiff = (Difference) allDiffs.get(i);
myDiffsList.add(new MyDifference(aDiff, refDocJdom2, resDocJdom2));
if(myDiffsList.size() == LIMIT)
return ;
if (i%25 == 0 && i!= 0){
popmsg("**************************************************\t"+i+"\n");
}
}
allDiffs.clear();
allDiffs = null;
}else{
popmsg("NO DIFERENCIES");
}
}发布于 2014-05-23 12:33:01
JDOM将整个XML文档读入内存中。这对于任何基于内存的XML模型(XOM/DOM/JDOM/等等)来说都是“正常”的。这也是众所周知的这些系统的弱点。最终,这个问题没有解决办法,同时仍然保留整个XML的内存表示形式。
当读取XML文档(通常是UTF-8)时,磁盘上的1GB数据通常按比例转换为内存中的许多字符,约为2GB。这就是对于1GB XML文档应该“预算”的内容。
SlimJDOMFactory重用XML中的string,而不是保留对新字符串的引用,本质上它不重复字符串值。当您有许多相同名称的元素、标记和其他结构时,这是非常方便的。例如,如果没有SlimJDOMFactory,一个包含1M <tag />元素的XML文档将有1万个不同的元素实例,每个实例都有自己的名称tag。假设tag大约是一个32字节的对象,那么需要大约32 to来存储这些字符串。SlimJDOMFactory将减少到只有32字节,但这只是“到目前为止”,它不能解决这样一个事实,即随着文档的增长,它将占用更多的空间……它只是‘延迟’,当你用尽了记忆。它还有一些其他的后果,不管是好的还是坏的.:好的,它减少了垃圾收集时间,因为用于扫描的内存较少,当文档不重复时,它会减慢(略微)文档加载时间。我的测试表明,即使是在内存中使用几个GC周期的文档,内存占用空间较小的文档的净收益很快就会实现,并且解析端的性能成本将得到“回报”。
解决这一问题的典型办法是:
这些解决方案中没有一个是“很棒”的,但这正是在内存中的XML系统所得到的。
https://stackoverflow.com/questions/23828671
复制相似问题