首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JDOM占用了太多内存

JDOM占用了太多内存
EN

Stack Overflow用户
提问于 2014-05-23 12:00:22
回答 1查看 2K关注 0票数 8

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

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

我试过使用SlimJDOMFactory,但仍然使用太多内存!!

实际上,我需要在XML文件中向前和向后导航。没有JDOM,我就找不到简单的方法。

有人能帮忙吗?

下面是关于如何构建JDOM文档的代码示例:

代码语言:javascript
复制
    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");
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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周期的文档,内存占用空间较小的文档的净收益很快就会实现,并且解析端的性能成本将得到“回报”。

解决这一问题的典型办法是:

  1. 直接使用SAX,完全没有内存模型.
  2. 将输入文件分割成较小的块。这是正常的解决方案,它有很多道理(它减少了延迟,您可以并行地解析文件,等等)。
  3. 逻辑上将XML拆分为仍然有效的XML部分,并在文件子集上使用特殊的InputStreams解析文件的部分。
  4. 向系统添加更多内存。
  5. 使用一个自定义JDOMFactory,它跳过您知道永远不需要的内容( JDOMFactory作为文档SAXBuild流程的一部分被调用.所以,你实际上可以把文件内容“修剪”到你知道你需要的那个子集.最后仍然是内存中的JDOM文档和可导航的(剩下的部分)。

这些解决方案中没有一个是“很棒”的,但这正是在内存中的XML系统所得到的。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23828671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档