Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JDOM使用了太多内存_Java_Xml_Heap Memory_Jdom_Xmlunit - Fatal编程技术网

Java JDOM使用了太多内存

Java JDOM使用了太多内存,java,xml,heap-memory,jdom,xmlunit,Java,Xml,Heap Memory,Jdom,Xmlunit,我有一个应用程序,它使用XmlUnit从两个XML文件中获取差异。 但问题是XmlUnit使用JDOM。我的xml文件大约有1GB大 在JDOM文档中存储这些xml需要太多的RAM 我曾尝试使用SlimJDOMFactory,但仍然使用了太多的RAM 实际上,我需要在XML文件中前后导航。没有JDOM,我找不到简单的方法 有人能帮忙吗 以下是关于如何构建JDOM文档的代码示例: private org.jdom2.Document refDocJdom2; private org

我有一个应用程序,它使用XmlUnit从两个XML文件中获取差异。 但问题是XmlUnit使用JDOM。我的xml文件大约有1GB大

在JDOM文档中存储这些xml需要太多的RAM

我曾尝试使用SlimJDOMFactory,但仍然使用了太多的RAM

实际上,我需要在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");
    }
}
private org.jdom2.Document refDocJdom2;
私有org.jdom2.Document resDocJdom2;
SAXBuilder sxb=新SAXBuilder();
setJDOMFactory(新SlimJDOMFactory());
popmsg(“验证引用文件…”);
试一试{
refDocJdom2=sxb.build(referenceXML\u路径);
}捕获(例外e){
showMessageDialog(null,“分析引用时出错:“+referenceXML_Path+”文件。\n检查XML文件的有效性。”);
返回;
}
popmsg(“已验证的参考文件”);
popmsg(“验证结果文件…”);
试一试{
resDocJdom2=sxb.build(resultXML\u路径);
}捕获(例外e){
showMessageDialog(null,“分析结果时出错”+resultXML_Path+“文件。\n检查XML文件的有效性。”);
返回;
}
popmsg(“结果文件已验证”);
popmsg(“验证完成”);
GetDifferenties(引用XML\u路径、结果XML\u路径);
d2=新日期();
}
public void getDifferentications(字符串fileRef、字符串fileRes)引发SAXException、IOException{
popmsg(“文档:有效的XML格式”);
popmsg(“差分剪切…”);
读者再阅读者;
refReader=新文件读取器(fileRef);
Reader resReader=新文件读取器(fileRes);
差异=新的差异(重新读取器、重新读取器);
if(refReader!=null){
refReader.close();
}
refReader=null;
if(resReader!=null){
resReader.close();
}
resReader=null;
//待办事项
//setIgnoreWhitespace(true);
MyDetailedDiff=新的DetailedDiff(差异);
MyDetailedDiff.overrideDifferenceListener(新的IgnoreNameDeletesDifferenceListener());
MyDetailedDiff.overrideElementQualifier(新元素名和属性均衡器());
AllDiff=MyDetailedDiff.getAllDifferences();
MyDetailedDiff=null;
popmsg(“获取所有差异…\n正在对它们进行排序…”);
popmsg(“Diff SIZE:+alldiff.SIZE());
myDiffsList=newArrayList(allDiffs.size());
如果(AllDiff.size()>0){
差分aDiff;
对于(int i=0;i
JDOM将整个XML文档读取到内存中。这对于任何基于内存的XML模型(XOM/DOM/JDOM/etc)来说都是“正常的”。这也是这些系统众所周知的弱点。最终,这个问题没有解决方案,但仍然保留整个XML的内存表示

读取XML文档(通常为UTF-8)时,磁盘上的1GB数据通常会按比例转换为内存中的许多字符,即2GB左右。这就是1GB XML文档的“预算”

SlimJDOMFactory重用XML中的字符串,而不是保留对新字符串的引用,本质上它消除了字符串值的重复。当您有许多具有相同名称的元素、标记和其他结构时,这非常方便。例如,如果没有SlimJDOMFactory,一个包含1M
元素的XML文档将有1M个不同的元素实例,每个实例都有自己的名称
标记
。假设
tag
是一个32字节的对象,那么存储这些字符串大约需要32MB。SlimJDOMFactory将把它减少到32字节,但是,这只是“目前为止”,它不能解决这样一个事实,即随着文档的增长,它将占用更多的空间。。。。。它只是在内存不足时“延迟”。它还有一些其他的后果,包括好的和坏的…:好的,它减少了垃圾收集时间,因为用于扫描的内存更少,它在消除重复时会减慢(稍微)文档加载时间。我的测试表明,对于在内存中存在几个GC周期的文档,较小内存占用的净好处很快就实现了,并且解析端的性能成本得到了“回报”

此问题的典型解决方案是:

  • 直接使用SAX,而根本没有内存模型
  • 将输入文件拆分为更小的块。这是正常的解决方案,出于许多原因(它减少了延迟,您可以并行解析文件,等等),这非常有意义
  • 从逻辑上将XML拆分为仍然有效的XML部分,并使用文件子集上的特殊InputStreams解析文件的部分
  • 为系统添加更多内存
  • 使用一个自定义的JDOMFactory,它跳过您知道永远不会需要的内容(JDOMFactory是作为文档构建过程的一部分调用的……因此,您实际上可以将文件内容“修剪”到您知道需要的子集……并且仍然会得到内存中的JDOM文档和navigables(剩下的部分)

  • 这些解决方案都不是“好的”,但这正是内存XML系统所能提供的。

    我不明白。你说你使用的是XmlUnit,但你展示了一些随机的JDOM代码。无论如何,如果你想浏览一个由WML文件构建的DOM树,你必须将其加载到内存中。我不知道如何让10公升的水适合1公升的b奥特尔。