非常に大量のデータを処理する高性能アプリケーションがあります。非常に短期間で膨大な量の情報を受信、分析、破棄しています。これにより、現在最適化しようとしている大量のオブジェクトチャーンが発生しますが、二次的な問題も発生します。ガベージコレクションが起動すると、クリーンアップ中に長い遅延が発生する可能性があります(長いとは、10〜100ミリ秒を意味します)。これは許容できる時間の99%ですが、約1〜2分間の短い時間枠では、ガベージコレクションが遅延を引き起こさないことを絶対に確認する必要があります。これらの期間がいつ発生するかは事前に知っており、この期間中にガベージコレクションが行われないようにする方法が必要なだけです。アプリケーションは.NET 4.0 Frameworkを使用してC#で記述されており、それが重要な場合はマネージコードとアンマネージコードの両方を使用します。
私の質問は;
注-このシステムは非常に複雑で、多くの異なるコンポーネントがあります。私は、プログラムのすべてのクラスにカスタムIDisposableインターフェイスを実装する必要があるアプローチを避けたいと考えています。
.NET 4.6は2つの新しいメソッドを追加しました: GC.TryStartNoGCRegion
および GC.EndNoGCRegion
これだけ。
_GCLatencyMode oldMode = GCSettings.LatencyMode;
// Make sure we can always go to the catch block,
// so we can set the latency mode back to `oldMode`
RuntimeHelpers.PrepareConstrainedRegions();
try
{
GCSettings.LatencyMode = GCLatencyMode.LowLatency;
// Generation 2 garbage collection is now
// deferred, except in extremely low-memory situations
}
finally
{
// ALWAYS set the latency mode back
GCSettings.LatencyMode = oldMode;
}
_
これにより、できる限りGCを無効にできます。次の状態になるまで、オブジェクトの大きなコレクションは実行されません。
GC.Collect()
を呼び出しますGCSettings.LatencyMode
_をLowLatency
以外に設定したtry
ブロックにいる間、メモリ使用量は非常に速く上昇する可能性があるため、これを行うときは注意してください。 GCが収集している場合は、何らかの理由で収集しています。システムに大量のメモリがある場合にのみ、真剣に考慮する必要があります。
質問3を参照すると、ファイルシステムI/Oまたはネットワーク経由で情報を受信している場合、バイト配列などのオブジェクトを再利用できますか?その情報をカスタムクラスに解析している場合は、それらも再利用してみてください。しかし、正確に何をしているかを知らなければ、あまり良いアドバイスをすることはできません。
以下も役立つMSDNの記事です。
注:_GCSettings.LatencyMode = GCLatencyMode.LowLatency
_は、_GCSettings.IsServerGC == false
_の場合にのみ設定できます。 IsServerGC
は_App.config
_で変更できます:
_ <runtime>
<gcServer enabled="false" />
</runtime>
_