C#.Net SaxonApi抛出内存异常

时间:2016-07-26 17:14:01

标签: c# .net saxon

机器配置为4CPU 16 GB RAM,并尝试处理800MB和300MB XML文件。有时,.NET Saxon API会在堆栈跟踪之下抛出内存不足的异常。看了前几个小时的perfstats,服务器似乎有10GB的可用内存。下面的代码是使用Task.Run()在Parallel Tasks中运行的。请指教。

 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)

1 个答案:

答案 0 :(得分:0)

对于一个800Mb的输入文件,我认为你可以开始达到除可用堆内存的实际数量之外的限制,例如数组的最大大小或字符串。这可能是你看到的效果。 TinyTree节省空间的一种方法是使用少量大型物体而不是大量小物体,因此它可能会触发这种效果。

TinyTree.condense()方法(它失败的地方)在树构造结束时被调用,并尝试回收用于TinyTree数据结构的数组中未使用的空间。这是通过将较小的阵列分配到所使用的实际大小并跨越复制数据来完成的。所以暂时需要额外的内存,这就是发生故障的地方。查看代码,实际上有机会减少所需的临时内存量。

如果您的数据中存在大量重复的文本或属性值,则可能值得使用" TinyTreeCondensed"试图共同使用这些值的选项。但如果没有这样的重复,这可能会适得其反,因为在树木构建过程中用于索引的空间。

由于数据如此之大,我认为检查替代策略是个好主意。例如:XML数据库;流处理;将文件拆分为多个文件;文件投影。如果不了解你想要解决的问题的大局,就无法就此提出建议。