ガベージコレクターがいつ呼び出されるか教えてください。バックグラウンドスレッドで継続的に実行されていますか? ガベージ コレクターは、メモリ フォーム ジェネレーションを消去する必要があることをどのように認識していますか?
4 に答える
ガベージ コレクターが実行されます。
- コードがメモリを割り当てようとしていて、ヒープに十分なスペースがない場合。
- システムがアプリケーションに信号を送信して、使用するリソースを減らした場合 (アプリケーションを最小化した場合など)。
- たとえば、ヒープ領域がほとんど残っておらず、アプリケーションがディスク I/O でビジー状態である場合など、ガベージ コレクタが有用であると判断した場合。
ガベージ コレクターが実行するタイミングを正確に決定する方法は実装の詳細であるため、フレームワークのバージョン間で異なる場合があります。
ガベージ コレクターは継続的に実行されません。実行すると、アプリケーション内の他のすべてのスレッドが凍結され、ガベージ コレクターがメモリを単独で制御できるようになります。
GC が収集しているかどうかを正確に知りたい場合は、次のクラスを使用できます。
public class GCWatcher
{
protected override void Finalize()
{
Debug.Print("GC on the prowl");
try {
if (!AppDomain.CurrentDomain.IsFinalizingForUnload() && !Environment.HasShutdownStarted) {
GCWatcher g = new GCWatcher();
}
} catch {
// nothing to do, but in case of error, the GC should continue anyway!
}
}
}
クラスは、GC によってファイナライズされるときにインスタンス化されます。また、GC が開始されたときにメッセージを出力します。
また、コメントに投稿されたリンクを参照して、こことここで.NET GC を深く掘り下げることもできます。
ガベージ コレクターは継続的に実行されていません。一度に 1 つの「コレクション」を実行します (複数の GC の「世代」に影響を与える可能性があります)。
それが呼び出されたとき(無視GC.Collect()
)は非決定論的であり、仕様の一部ではなく、CLRの実装の詳細であると私は信じています。
とはいえ、現在の .NET GC は、プログラムがマネージ ヒープにメモリを割り当てようとして、連続した空きメモリが十分にない場合に実行されます。コレクションはスペースを解放し、ヒープのコンテンツを最適化して、割り当てを実行するためのスペースを残します。
Gen0 コレクションに残っているものはすべて Gen1 に昇格されます。プロモートされたアイテムに対して Gen1 に十分なスペースがない場合、Gen1 も収集されます。Gen1 と Gen2 の間でも同じことが起こります。
- Gen 0 オブジェクトが最大 256 KB に達するとき。
- Gen 1 オブジェクトが ~ 2Mb に達するとき。
- Gen 2 オブジェクトが最大 10Mb に達するとき。
- システム メモリが不足している場合。