2016-07-26 107 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的文件。 –