将文档添加到文档列表时的Java堆空间

时间:2014-01-18 00:22:47

标签: java xml out-of-memory

我正在使用import org.w3c.dom.Document;对于文件。

我有这个代码块来解析arraylist fileList中的xml文件,有超过2000个xml文件要解析,xml文件的大小大约是30-50 Kb,解析文件没问题:

    try {
        for(int i = 0; i < fileList.size(); i++) {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(fileList.get(i)); //<------ error will point here when docList.add(doc) is uncommented.
            docList.add(doc); 
        }
    } catch (ParserConfigurationException | SAXException | IOException e) {
        e.printStackTrace();
    }

但每当我将它们添加到列表中时,都会出现此错误:

线程“main”中的异常java.lang.OutOfMemoryError:Java堆空间     at com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.createChunk(Unknown Source)     at com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.ensureCapacity(Unknown Source)     at com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.createNode(Unknown Source)     at com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.createDeferredTextNode(Unknown Source)     at com.sun.org.apache.xerces.internal.parsers.AbstractDOMParser.characters(Unknown Source)     at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)     at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)     at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)     在com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(未知来源)     at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)     at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)     在javax.xml.parsers.DocumentBuilder.parse(未知来源)     在com.test.parser.Parser.getDocs(Parser.java:146)     在com.test.parser.Parser.main(Parser.java:50)

取消注释docList.add(doc)不会产生此异常,不知道为什么会发生这种情况?

编辑:我在运行配置中将-Xmx1024M添加到VMArguments并且运行正常。

2 个答案:

答案 0 :(得分:1)

uncommenting the docList.add(doc) does not produce this exception, any idea why this is happening?

这很简单:如果不在doc中存储docList引用,那么doc引用将被新对象 - Document doc = builder.parse(fileList.get(i));所覆盖,因此上一次迭代的doc将是孤儿 - 没有参考的对象。这个将被JVM垃圾收集器快速删除,因此在循环期间,堆上最多有2个doc对象。

但是,在docList.add(doc)处于活动状态时,您仍然会引用在循环中创建的所有doc对象:完全fileList.size()个实例。它们不会被垃圾收集器收集(并从堆中删除),因为docList将对它们进行有效的活动引用。

如何避免OutOfMemoryError?在销毁以前文档的DOM对象之后,只需逐个解析/处理文档,或者考虑使用流式解析器,例如SAXParser

答案 1 :(得分:0)

右键单击项目文件夹 单击-> runAs->运行配置->单击参数选项卡->添加

-xmx512M按Enter -xmx2048M

应用并运行。