私のアプリケーションは、大量のバイナリ シリアライゼーションと大きなオブジェクトの圧縮を行います。非圧縮のシリアル化されたデータセットは約 14 MB です。圧縮すると約 1.5 MB になります。データセットで serialize メソッドを呼び出すたびに、大きなオブジェクト ヒープのパフォーマンス カウンターが 1 MB 未満から約 90 MB に跳ね上がることがわかりました。また、比較的負荷の高いシステムでは、通常、このシリアライゼーション プロセスが数回発生するしばらく (数日) 実行した後、このシリアライゼーション メソッドが呼び出されると、アプリケーションがメモリ不足の例外をスローすることが知られています。メモリは十分にあるようです。断片化が問題であると推測しています (100% 確信しているとは言えませんが、ほぼ確実です)。
私が考えることができる最も簡単な短期的な修正(短期と長期の両方の答えを探していると思います)は、シリアル化プロセスが完了した直後に GC.Collect を呼び出すことです。私の意見では、これはLOHからオブジェクトをガベージコレクションし、他のオブジェクトを追加する前に行う可能性があります。これにより、断片化をあまり引き起こすことなく、他のオブジェクトがヒープ内の残りのオブジェクトにぴったりと収まるようになります。
このばかげた 90MB の割り当て以外に、失われた LOH を使用するものは他にないと思います。この 90 MB の割り当ても比較的まれです (約 4 時間ごと)。もちろん、そこにはまだ 1.5 MB の配列があり、おそらく他のいくつかの小さなシリアル化されたオブジェクトがあります。
何か案は?
良い反応の結果として更新
これが仕事をする私のコードです。私は実際にこれを変更して、シリアル化中に圧縮して、シリアル化が同時にストリームにシリアル化されるようにしましたが、あまり良い結果は得られませんでした。また、メモリ ストリームを 100 MB に事前割り当てし、同じストリームを 2 回続けて使用しようとしましたが、とにかく LOH は最大 180 MB になりました。Process Explorer を使用して監視しています。それは非常識です。次に UnmanagedMemoryStream のアイデアを試してみようと思います。
そうでない場合は、試してみることをお勧めします。この正確なコードである必要はありません。大規模なデータセットをシリアル化するだけで、驚くべき結果が得られます (私のものには、約 15 のテーブルがあり、文字列と列がたくさんあります)。
byte[] bytes;
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer =
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
System.IO.MemoryStream memStream = new System.IO.MemoryStream();
serializer.Serialize(memStream, obj);
bytes = CompressionHelper.CompressBytes(memStream.ToArray());
memStream.Dispose();
return bytes;
UnmanagedMemoryStream でバイナリ シリアル化を試行した後に更新する
UnmanagedMemoryStream にシリアル化しても、LOH は同じサイズにジャンプします。私が何をしても、BinaryFormatter を呼び出してこの大きなオブジェクトをシリアル化すると、LOH が使用されるようです。事前割り当てに関しては、あまり役に立たないようです。100MBを事前に割り当ててからシリアライズすると、170MBが使用されます。これがそのコードです。上記のコードよりもさらに簡単
BinaryFormatter serializer = new BinaryFormatter();
MemoryStream memoryStream = new MemoryStream(1024*1024*100);
GC.Collect();
serializer.Serialize(memoryStream, assetDS);
真ん中の GC.Collect() は、LOH パフォーマンス カウンターを更新するためだけのものです。正しい 100 MB が割り当てられることがわかります。しかし、シリアライズを呼び出すと、すでに割り当てられている 100 の上にそれが追加されているように見えることに気付くでしょう。