5

私はクライアントにデシリアライズされた大きなオブジェクト(〜115Mb)をクライアントに送信している.NET 4 WCFサービスを持っています。最初にオブジェクトが入ってくると、それはデシリアライズされます。ただし、以降の呼び出しではすべてOutOfMemoryExceptionが返されます。私はIDisposablesのすべてがusingブロックに包まれていることを確認しました。私はBinaryFormatter outofmemory exception deserialization Deserialize from MemoryStream throws OutOfMemory exception in C# のようなこれに似た他の質問を見てきました。私はSimon Hewitt's Optimized Serializerを使用するなど、人々が推奨しているソリューションのいくつかを試しました。しかし、結局のところ、オブジェクトを逆シリアル化するために彼は依然としてBinaryFormatterに依存しています。BinaryFormatter.DeserializeからのOutOfMemory例外(内部StringBuilder呼び出しから)

私はOutOfMemoryExceptionを捕まえて、スタックトレースを見ました(下記参照)。トレースは、StringBuilderクラスのメモリ使用に関する問題から発生しているようです。私はStringBuilderが、より多くのスペースが必要なときに使用する(長さ* 2)アルゴリズムのために、メモリの問題を引き起こす可能性のある他の記事を読んだことがあります。

at System.Text.StringBuilder.ToString()  
at System.IO.BinaryReader.ReadString()  
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectString(BinaryHeaderEnum binaryHeaderEnum)  
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()  
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)  
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)  
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream) 

異なる動作とStringBuilderを使用するか、より良いメモリを管理BinaryFormatterに良い代替があるないためにBinaryFormatterを取得する方法はありますか?

+0

最初の呼び出しでも同じサイズのオブジェクトでしたか?あなたのためにいくつかのコードを投稿できますか? –

+0

はい、どちらの場合もまったく同じ応答でした。私は毎回正確なバイトサイズを確認して確認しました。私はいくつかのコードを引き出すことができるかどうかを見ていきますが、かなり長いです。 – MrWuf

答えて

1

BinaryFormatterを使用することはお勧めできません。実際には、binaryformatterを使用していない場合はもっと小さくなります。表形式のデータなどの単純なデータや循環参照がないなどの制約がある場合は、簡単なバイナリライタで独自のバイナリシリアル化を行うか、protobuf-netまたはjson.netのようなシェルフシリアライザを使用してコンパクト化する必要があります。はるかに速い。