2014-01-18 50 views
1

我正在使用import org.w3c.dom.Document;爲文件。將文檔添加到文檔時的Java堆空間文檔列表

我有這段代碼,它解析來自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(); 
    } 

但每當我將它們添加到列表中這個錯誤出現:螺紋

異常 「主要」 java.lang.OutOfMemoryError:Java堆空間 在com.sun.org。 apache.xerces.internal.dom.DeferredDocumentImpl.createChunk(未知來源) 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) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source) at 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在運行配置和它的工作。

+1

爲什麼每次通過循環時都會創建所有事物的新實例? – csmckelvey

+1

相當粗略的估計說,你將需要大約140 MB的RAM。增加Java堆大小:'-Xmx400M'。 –

+0

@csmckelvey,我只是試驗代碼,因爲我得到這個錯誤,我有一個不同的DocumentBuilder之外的for循環。 –

回答

1

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

原因很簡單:沒有docList存儲doc參考,引用文檔將被新的對象overrived - 對象沒有參考 - Document doc = builder.parse(fileList.get(i));,所以從以前的迭代doc將是孤兒。這個將被JVM垃圾收集器快速刪除,所以在循環中,堆中最多隻有2個doc對象。

但是,在docList.add(doc)處於活動狀態時,仍然會引用所有在循環中創建的doc對象:完全爲fileList.size()實例。它們不會被垃圾收集器收集(並從堆中移除),因爲docList將具有有效的活動引用。

如何避免OutOfMemoryError?只需在破壞前一個doc的DOM對象之後逐個解析/處理文檔,或者考慮使用流解析器,例如SAXParser

相關問題