情况是我正在对远程服务器进行 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)
我已经阅读过,这是因为大对象堆太碎片化了,所以即使在调用之前快速检查 StringBuilder.EnsureCapacity 只会导致提前抛出 OutOfMemoryException (因为我在猜测需要什么,它实际上可能不需要那么多,所以我的检查导致的问题多于解决的问题)。有些意见是我对此无能为力。
我问过自己的一些问题:
- 使用更少的内存 - 你检查过泄漏吗?是的。内存使用量会上升和下降,但没有基本的增长可以保证这种情况发生。有时它失败了,它在之前的那个阶段成功了。
- 转移较小的金额不是一个选项,这是我无法控制的第三方网络服务(或者至少需要很长时间才能解决,同时我仍然有问题)
- 你能对 LOH 做些什么来降低它失败的可能性吗?...现在这是最富有成效的课程。这是一个 32 位进程(它必须出于各种政治、技术和无聊的原因),但通常有数百兆免费(我们见过失败的最大数量的倍数)。
- 我们可以监控 LOH 吗?使用 perfmon 我可以跟踪堆的大小,但我认为没有办法监控最大的可用连续内存块。
问题是:对尝试的事情有什么建议或建议吗?