状況は、XML ドキュメントを文字列として返すリモート サーバーに対して WCF 呼び出しを行っていることです。
ほとんどの場合、この戻り値は数 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 がより早くスローされます (必要なものを推測しているため)。 、実際にはそれほど必要ないかもしれないので、私のチェックは解決するよりも多くの問題を引き起こしています)。私にできることはあまりないという意見もあります。
私が自分自身に尋ねた質問のいくつか:
- メモリの使用量を減らします - リークをチェックしましたか? はい。メモリ使用量は増減しますが、これを保証する基本的な増加はありません。失敗することもありますが、以前はその段階で成功していました。
- 少額の送金オプションではありません。これはサードパーティの Web サービスであり、私には制御できません (または、少なくとも解決には長い時間がかかります。それまでの間、まだ問題があります)。
- LOH が失敗する可能性を低くするために、LOH に何かできることはありますか? ...今、これは最も実り多いコースです。これは 32 ビット プロセスですが (さまざまな政治的、技術的、および退屈な理由でそうする必要があります)、通常は数百メガバイトの空き領域があります (これまでに見られた失敗の最大量の倍数)。
- LOH を監視できますか? perfmon を使用すると、ヒープのサイズを追跡できますが、使用可能な最大の連続したメモリ ブロックを監視する方法はないと思います。
質問: 試してみるべきことについて何かアドバイスや提案はありますか?