.NET アプリケーションの高速化について探し始めてみた - その8 - ( .NETFramework の GC )
今回は、.NETFramework の GC の種類に関する記事です。ここの記事が参考になります。これは全く知見がありませんでした。下記のような種類があるそうです。
- ワークステーション/コンカレント実行なし ―― メモリ割り当てに責任を持つマネージスレッドにおいて利用できるメモリ空間が不足すると、同じスレッドで動作するGCが呼び出される。GCは他の全てのマネージスレッドを停止し、メモリを片づけて、停止したマネージスレッドの動作を再開し、元のスレッドに制御を返す。
- ワークステーション/コンカレント実行あり(コンカレントGCとも呼ばれる) ―― 上のシナリオに似ているが、GCが使われていないメモリを回収する間、マネージスレッドをずっと停止しておくわけではない。マネージスレッドは自身の作業を続けることができ、メモリを割り当てることも可能だが、下に記述するような若干の制限がある。gen0オブジェクトのためのメモリプールは、割り当てのニーズを満たすために、前のシナリオの場合よりも大幅に大きい。利用可能なメモリがなくなれば、スレッドはやはり停止させられる。
- サーバー ―― こちらの場合は、CPUごとに、専用のスレッドとメモリヒープで動作するGCが存在する。メモリを割り当てるスレッドにおいて利用できるメモリ空間が不足すると、そのスレッドはGCスレッドに通知する。GCは各CPUで動作しているマネージスレッドをすべて停止し、メモリを片づけ、作業を終えたことを通知し、停止したスレッドを再開する。
GCの種類は、ランタイム構成ファイルに<gcConcurrent></gcConcurrent>と<gcServer></gcServer>を設定することで選択できる。そして、GCの介入は、実行時にLatencyModeプロパティをGCLatencyMode値の中の1つ(Batch、Interactive、LowLatency)にセットすることで設定できる。
アプリケーション構成ファイルに以下のように設定すればいいんでしょうか。
<configuration> <runtime> <gcConcurrent enabled="false"/> <gcServer enabled="true"/> </runtime> </configuration>
GCSetting というクラスがあるんですね。IsServerGC, LatencyMode というプロパティを保持しています。IsServerGC はアプリケーション構成ファイルに設定可能なようです。LatencyMode は下記の種類があります。
- Batch:ガベージ コレクションの同時実行を無効にし、バッチ呼び出しでオブジェクトを解放します。 これは、最もアプリケーション影響を与えるモードです。このモードは、スループットを最大化するようにデザインされているため、応答性は低下します。このモードは、<gcConcurrent> ランタイム構成の設定をオーバーライドします。 <gcConcurrent> が有効な場合は、Batch モードに切り替えることで、それ以降の同時実行コレクションを抑止できます。
- Interactive:ガベージ コレクションの同時実行を有効にし、アプリケーションの実行中にオブジェクトを解放します。 これは、ワークステーションのガベージ コレクションの既定のモードであり、Batch ほどアプリケーションに影響を与えません。 このモードでは、応答性とスループットのバランスが保たれます。このモードは、ワークステーション上の同時実行ガベージ コレクションと同じです。
- LowLatency:オブジェクトの解放についてより保守的なガベージ コレクションを有効にします。 ジェネレーション 0 とジェネレーション 1 のコレクションの発生頻度は上昇するかもしれませんが、フル コレクションはシステムがメモリ不足状態にある場合にのみ発生します。このモードは、サーバーのガベージ コレクターでは使用できません。
- SustainedLowLatency:長い期間で見た遅延を最小限にするガベージ コレクションを有効にします。 ガベージ コレクターは、ジェネレーション 0 とジェネレーション 1 のコレクション、およびジェネレーション 2 の同時実行ガベージ コレクションのみを実行しようとします。 システムがメモリ不足になっている場合には、ブロックを伴うフル コレクションが発生する可能性があります。
それぞれのプログラムが配置される場所によって、きちんと設定すると良さそうです。高パフォーマンスを目指すシステムならば、このようなこともきちんと設定したいですね。