Uns*_*ced 5 c# wcf stringbuilder out-of-memory
情况是我正在对远程服务器进行WCF调用,该服务器将XML文档作为字符串返回.
大多数时候这个返回值是几K,有时几十K,非常偶尔几百K,但很少可能是几兆(第一个问题是我无法知道).
正是这些罕见的场合引起了悲伤.我得到一个开始的堆栈跟踪:
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Xml.BufferBuilder.AddBuffer()
at System.Xml.BufferBuilder.AppendHelper(Char* pSource, Int32 count)
at System.Xml.BufferBuilder.Append(Char[] value, Int32 start, Int32 count)
at System.Xml.XmlTextReaderImpl.ParseText()
at System.Xml.XmlTextReaderImpl.ParseElementContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlTextReader.Read()
at System.Xml.XmlReader.ReadElementString()
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderMDRQuery.Read2_getMarketDataResponse()
at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer2.Deserialize(XmlSerializationReader reader)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
Run Code Online (Sandbox Code Playgroud)
我已经阅读了,因为大对象堆刚刚变得过于分散,所以即使在调用之前快速检查StringBuilder.EnsureCapacity只会导致OutOfMemoryException被提前抛出(因为我猜测需要什么) ,它可能实际上并不需要那么多,所以我的检查引起的问题比它解决的问题多得多.有些意见认为我无能为力.
我问过自己的一些问题:
问题是:对于要尝试的事情有什么建议或建议吗?
您可以查看绑定的TransferMode属性,以查看是否满足将其从默认值"Buffered"更改为" Streamed "或" StreamedResponse "的要求.
另外,请查看maxBufferPoolSize和maxBufferSize的值.增加内部缓冲区的大小有助于内存利用率,尤其是处理大型消息时.
如果您收到大量邮件,也可能已经设置了maxReceivedMessageSize,但我也会查看该值.
我已经看到上面的一个值,如果超过阈值,则会出现与内存相关的模糊信息.原始异常实际上是隐藏在我的应用程序中的消息.启用WCF跟踪有助于诊断问题并查看真正的错误 - 我需要增加上面一个或多个绑定属性的值.
我对你在帖子中使用的绑定没有感觉,但我相信这些设置在主要的设置中很常见.例如,查看basicHttpBinding上的MSDN文档.
如果它真的是LOH碎片,一旦调整工作耗尽,就没有什么可以做的.可能需要滚动回收应用程序来缓解它(我讨厌推荐)但如果你已经用尽了其他的努力,你可能会留下它.