ガベージコレクターは、オブジェクトと変数がスコープ外であることをどのようにして認識し、ガベージコレクターで収集できるようにしますか?
4 に答える
つまり、すべてのアプリケーションには一連のルートがあります。ルートは、管理対象ヒープ上のオブジェクトまたはnullに設定されているオブジェクトを参照するストレージの場所を識別します。
ガベージコレクターが実行を開始すると、ヒープ内のすべてのオブジェクトがガベージであると想定されます。
ガベージコレクターは、ルートを歩き始め、ルートから到達可能なすべてのオブジェクトのグラフを作成します。
到達できないすべてのオブジェクトが削除されます(メモリが解放されます)
これはhttp://msdn.microsoft.com/en-us/magazine/bb985010.aspxから取得されます-ガベージコレクションに関する優れた記事です。あなたにとって「興味深い」部分は「ガベージコレクションアルゴリズム」です。それほど長いセクションではありません
.NETでのガベージコレクションの説明は、レイモンドチェンの優れた一連のブログ投稿を参照せずに完了することはできません。
- 誰もがガベージコレクションについて間違った方法で考えています
- オブジェクトがガベージコレクションに利用できるようになるのはいつですか?
- 誰もがCLRオブジェクトについて間違った方法で考えています(誰もがそうではありません)
- いつGC.KeepAliveを使用する必要がありますか?
シリーズの最初の記事からの引用は次のとおりです。
誰かにガベージコレクションとは何かを尋ねると、おそらく「ガベージコレクションは、オペレーティング環境がプログラムで使用されなくなったメモリを自動的に再利用するときです。これはメモリをトレースすることによって行われます。ルートから始めて、アクセス可能なオブジェクトを特定します。」
この説明は、メカニズムと目標を混同します。消防士の仕事は「赤いトラックを運転して水を噴霧すること」だと言っているようなものです。これは消防士が行うことの説明ですが、仕事の要点(つまり、火を消す、より一般的には防火)を見逃しています。
そして、ここに彼が示すいくつかの興味深い点があります:
正しく記述されたプログラムは、ファイナライザーが実行されることを想定できません。
コードブロック内のオブジェクトは、それが呼び出した関数の実行中に収集の対象になる可能性があります。
メソッドのパラメータは、メソッドの実行中に収集の対象になる可能性があります。
奇妙な現実世界の例え:ガベージコレクターは、ダイバーがまだ空中にいる場合でも、ダイバーが最後に飛び込み台に触れるとすぐに飛び込み台を収集できます。
そして、最も簡潔に:
GCをルートのトレースとは考えないでください。GCは、使用しなくなったものを削除するものと考えてください。
ガベージコレクター(GC)は、アプリケーションのメモリの割り当てと解放を管理するために共通言語ランタイム(CLR)によって初期化される.NETFrameworkの一部です。
ガベージコレクターの種類
ガベージコレクタは、さまざまなシナリオで機能します。CLRは、次の種類のガベージコレクションを提供します。
- ワークステーションのガベージコレクション(GC)は、通常の優先スレッドで実行され、同時実行または非同時実行が可能で、クライアントアプリ用に設計されています
- サーバーガベージコレクションはサーバーアプリケーション用に設計されており、論理CPUごとに個別のマネージヒープと対応するガベージコレクションスレッドを作成します。スレッドは最高の優先度で実行されるため、スレッドは高速になりますが、リソースを大量に消費します。.NET Coreでは、.NET Framework 4.5以降のバージョンのサーバーのガベージコレクションは、非並行またはバックグラウンドで実行できます。.NET Framework 4以前のバージョンでは、サーバーのガベージコレクションは同時実行ではありません。
同時ガベージコレクション 同時ガベージコレクションを使用すると、ユーザースレッドを第2世代のガベージコレクションのほとんどで実行できます。管理対象ヒープに新しい割り当て用の空き領域がまだある限り、ユーザースレッドは実行して新しいオブジェクトを作成できます。
非同時ガベージコレクション 非同時ガベージコレクションは、ガベージコレクションの全期間中、すべての非ガベージコレクションスレッドを一時停止し、その間、アプリケーションを効果的に一時停止します。
バックグラウンドガベージコレクション バックグラウンドガベージコレクションは、同時ガベージコレクションの代わりになります。これは同時ガベージコレクションに似ていますが、第0世代と第1世代のガベージコレクションが進行中の第2世代のガベージコレクションを中断し、プログラムの実行を一時的にブロックできるようにします。第0世代と第1世代のガベージ・コレクションが完了した後、プログラムの実行と第2世代のガベージ・コレクションの両方が続行されます。これにより、ガベージコレクションのためにプログラムの実行が一時停止される時間がさらに短縮されます。
メモリとマネージドヒープ ガベージコレクターが共通言語ランタイム(CLR)によって初期化されると、オペレーティングシステムのネイティブヒープとは対照的に、マネージドヒープと呼ばれるメモリのセグメントを割り当てて、オブジェクトを格納および管理します。
管理対象プロセスごとに、ガベージコレクターは、Windows VirtualAlloc関数を使用して、管理対象ヒープ内のメモリのセグメントを予約します。(Windows VirtualFree関数を使用して、セグメントをOSに解放します)。プロセス内のすべてのスレッドは、同じヒープ上のオブジェクトにメモリを割り当てます。
考慮すべき重要なことの1つは、割り当てられた各セグメントのサイズは実装固有であり、いつでも変更される可能性があることです。
世代
管理対象ヒープに格納されるオブジェクトは、年齢に応じて世代ごとに編成されます。ガベージコレクションは、主に、ヒープのごく一部しか占有しない短命のオブジェクトの再生によって発生します。
- ジェネレーション0:存続期間の短いオブジェクトを持つ最年少のジェネレーション(例:一時変数または新しく割り当てられたオブジェクト(ラージオブジェクトでない場合は、ジェネレーション2コレクションのラージオブジェクトヒープに配置されます)
- ジェネレーション1:ガベージコレクションの実行で解放されないジェネレーション0オブジェクトによって占有されているスペースの場合、これらのオブジェクトはジェネレーション1に移動され、短命のオブジェクトが含まれます。
- ジェネレーション2。次のガベージコレクションの実行で解放されないジェネレーション1オブジェクトによって占有されているスペースの場合、これらのオブジェクトはジェネレーション2に移動されます。このジェネレーションには、存続期間の長いオブジェクト(つまり、サーバーアプリケーション内のオブジェクトで、プロセスの期間)。
ガベージコレクターは、ある世代の生存率が高いことを検出すると、その世代の割り当てのしきい値を増やします。
ガベージコレクタフェーズ
収集は、次のいずれかの条件によってトリガーされます。
システムの物理メモリが少なくなっています。これは、OSからのメモリ不足通知、またはホストによって示されるメモリ不足のいずれかによって検出されます。
管理対象ヒープに割り当てられたオブジェクトによって使用されるメモリが、許容可能なしきい値を超えています。このしきい値は、プロセスの実行中に継続的に調整されます。
GC.Collectメソッドが呼び出されます。ほとんどの場合、ガベージコレクターは継続的に実行されるため、このメソッドを呼び出す必要はありません。
この時点で、ガベージコレクタパスは次のフェーズをスローします。
マーキングフェーズ
:GC は、次の情報を使用してオブジェクトがライブであるかどうかを判断することにより、すべてのライブオブジェクトのリストを作成します(リストにないすべてのオブジェクトは削除される可能性があります) 。- スタックルート。ジャストインタイム(JIT)コンパイラーとスタックウォーカーによって提供されるスタック変数。JITの最適化により、スタック変数がガベージコレクターに報告されるコードの領域を長くしたり短くしたりできます。
- ガベージコレクションハンドル。管理対象オブジェクトを指し、ユーザーコードまたは共通言語ランタイムによって割り当てることができるハンドル。
- 静的データ。他のオブジェクトを参照している可能性のあるアプリケーションドメイン内の静的オブジェクト。各アプリケーションドメインは、静的オブジェクトを追跡します。
再配置フェーズ:すべてのライブオブジェクトのリストにあったすべてのオブジェクトの参照は、再配置フェーズで更新され、圧縮フェーズでオブジェクトが再配置される新しい場所を指すようになります。圧縮フェーズ:死んだオブジェクトが占めていたスペースを再利用し、生き残ったオブジェクトを圧縮します。圧縮フェーズでは、ガベージコレクションを生き残ったオブジェクトをセグメントの古い方の端に移動します。ヒープは、圧縮フェーズで圧縮されます。これは、死んだオブジェクトが占めていたスペースが解放され、残っている生きているオブジェクトが移動されるためです。ガベージコレクション後に残っているすべてのライブオブジェクトは、元の順序でヒープメモリの古い方の端に移動されます
資力
公式ドキュメント:https ://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals
http://msdn.microsoft.com/en-us/magazine/bb985010.aspxにアクセスしてください。それが言うように
ガベージコレクターは、アプリケーションで使用されなくなったオブジェクトがヒープ内にあるかどうかを確認します。そのようなオブジェクトが存在する場合、これらのオブジェクトによって使用されているメモリを再利用できます。