我正在使用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并且运行正常。
答案 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
应用并运行。