2016-07-26 142 views
0

機器配置爲4CPU 16 GB RAM,並嘗試處理800MB和300MB XML文件。 .NET Saxon API有時會在堆棧跟蹤下拋出內存異常。看着前幾個小時的perfstats,服務器似乎有10GB的空閒內存。下面的代碼使用Task.Run()在並行任務中運行請指教。C#.Net SaxonApi拋出內存異常

DocumentBuilder documentBuilder = processor.NewDocumentBuilder(); 
documentBuilder.IsLineNumbering = true; 
documentBuilder.WhitespacePolicy = WhitespacePolicy.PreserveAll; 
XdmNode _XdmNode = documentBuilder.Build(xmlDocumentToEvaluate); 

System.Exception: Error in ExecuteRules method ---> System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. 
    at net.sf.saxon.tree.tiny.TinyTree.condense(Statistics) 
    at net.sf.saxon.tree.tiny.TinyBuilder.close() 
    at net.sf.saxon.event.ProxyReceiver.close() 
    at net.sf.saxon.pull.PullPushCopier.copy() 
    at net.sf.saxon.event.Sender.sendPullSource(PullSource , Receiver , ParseOptions) 
    at net.sf.saxon.event.Sender.send(Source source, Receiver receiver, ParseOptions options) 
    at net.sf.saxon.Configuration.buildDocument(Source source, ParseOptions parseOptions) 
    at net.sf.saxon.Configuration.buildDocument(Source source) 
    at Saxon.Api.DocumentBuilder.Build(XmlReader reader) 
    at Saxon.Api.DocumentBuilder.Build(XmlNode source) 
+0

不,我仍在調查並尋求一些幫助,如果撒克遜API有任何建議。 –

+0

如果應用程序在64位計算機上以32位運行,SAXON API會導致大文件的內存不足異常... –

回答

0

隨着800MB輸入文件我想你可以開始打比可用堆內存的實際數量等限制,例如數組或字符串的最大尺寸。這可能是你看到的效果。 TinyTree節省空間的一種方式是使用少量大對象而不是大量小對象,因此可能會觸發這種效果。

TinyTree.condense()方法(即失敗的地方)在樹構造結束時調用,並試圖回收用於TinyTree數據結構的數組中未使用的空間。這是通過分配更小的陣列來達到實際使用的大小,並跨數據複製來完成的。所以暫時需要額外的內存,而這正是發生故障的地方。查看代碼,實際上有機會減少所需的臨時內存量。

如果數據中有很多重複的文本或屬性值,那麼可以使用「TinyTreeCondensed」選項來嘗試共享這些值。但是,如果沒有這種重複,這可能會適得其反,因爲樹木建設過程中用於索引的空間。

有了這麼大的數據,我認爲檢查替代策略是個好主意。例如:XML數據庫;流式處理;將文件分割成多個文件;文件投影。如果不知道你想要解決什麼問題的全貌,就不可能就此提出建議。

+0

我已實施改進以減少TinyTree.condense()期間使用的臨時空間 - 請參閱https: //saxonica.plan.io/issues/2857 –

+0

謝謝邁克爾。我也試圖將我的應用程序編譯爲平臺目標x64以查看它是否解決了內存不足問題。一旦我測試會更新。 –

+0

編譯應用程序到平臺目標x64,內存錯誤得到解決,並且能夠處理大於800MB的文件。 –