.Netガベージコレクションメカニズムはアルゴリズムと世代の年齢を理解します

.Netガベージコレクションメカニズムはアルゴリズムと世代の年齢を理解します

ガベージ コレクターは基本的に、すべてのオブジェクトが参照されている場所を追跡し、オブジェクトが参照されなくなった状況に注意し、対応するメモリを再利用する役割を担います。 .NET プラットフォームでも同じことが言えます。.NETガベージ コレクションのパフォーマンスを効果的に向上させることで、プログラムの実行効率を向上させることができます。

実際、ガベージ コレクションは Java で登場したわけではありません。1958 年にはすでに、チューリング賞を受賞した John が発明した Lisp 言語に GC 機能が搭載されていました。これが GC の初登場であり、ひらめきでした。その後、1984 年に Dave Ungar によって発明された Smalltalk 言語が初めて GC メカニズムを正式に採用しました。 .Net のガベージ コレクション メカニズムは大きな話題です。C++ などの言語に触れたことがなければ、GC がいかに重要で興味深いものであるかを理解するのは難しいでしょう。

1. ソフトウェア システムの結合性を向上させます。

2. プログラマーが破壊の処理に集中しなくても済むように、プログラミングの複雑さを軽減します。

3. 設計者がシステム抽象化を実行することを妨げません。

4. 不適切なメモリ使用によって発生するバグを削減します。

5. メモリ管理作業をプログラム作成から実行時に正常に移行し、予測できない管理上の脆弱性を予測可能にします。

1. アルゴリズム

ガベージ コレクターの本質は、参照されているすべてのオブジェクトを追跡し、参照されなくなったオブジェクトを整理し、対応するメモリをリサイクルすることです。これは「参照カウント」と呼ばれるアルゴリズムに似ていますが、このアルゴリズムはすべてのオブジェクトを走査して参照を維持する必要があるため、効率が低く、「循環参照」が発生するとメモリ リークが簡単に発生する可能性があります。そのため、.Net では上記のタスクを完了するために「マークスイープ」と呼ばれるアルゴリズムが使用されます。名前が示すように、「マーク アンド スイープ」アルゴリズムには 2 つの機能があります。

「マーキング」機能 - ガベージ識別: アプリケーションのルートから開始し、相互参照関係を使用して、ヒープ上に動的に割り当てられたすべてのオブジェクトをトラバースします。参照されていないオブジェクトはマークされず、ガベージになります。生き残ったオブジェクトはマークされ、「ルート オブジェクト到達可能性グラフ」が維持されます。実際、CLR はオブジェクトの関係を「ツリー グラフ」として扱います。データ構造を理解している学生なら、「ツリー グラフ」の概念によってオブジェクトのトラバースが高速化されることは間違いありません。

オブジェクト参照を検出してマークすることは、非常に興味深いタスクです。これを行うには多くの方法がありますが、最も効率的な方法は 1 つだけです。.Net では、これはスタックを使用して行われ、スタックを継続的にプッシュおよびポップすることで検出が完了します。まず、ツリー ダイアグラムで検出するオブジェクトを選択し、オブジェクトへのすべての参照をスタックにプッシュし、スタックが空になるまでこのプロセスを繰り返します。スタックが空になるということは、このローカル ルート (またはツリー グラフ内のノード) から到達可能なすべてのオブジェクトがトラバースされたことを意味します。ツリー グラフ ノードのスコープには、ローカル変数 (実際、ローカル変数はスコープが明確で制御しやすいため、すぐにリサイクルされます)、レジスタ、および静的変数が含まれます。これらの要素に対してこの操作を繰り返す必要があります。それが完了すると、メモリはオブジェクトごとにチェックされ、マークされていないオブジェクトはガベージになります。

「クリア」機能 - メモリの再利用: Compact アルゴリズムを有効にし、メモリ内の残存オブジェクトを移動し、それらのポインターを変更してメモリ内で連続するようにします。これにより、空きメモリも連続し、メモリの断片化の問題が解決されます。新しいオブジェクトに再度メモリを割り当てるときに、CLR は断片化されたメモリ内で新しいオブジェクトに適したメモリ領域を探す必要がないため、割り当て速度が大幅に向上します。

しかし、大きなオブジェクト (大きなオブジェクト ヒープ) を除いて、CPU が現在安価ではないことを認識しているため、GC はメモリ内の巨大なオブジェクトを移動しません。通常、大きなオブジェクトの存続期間は長くなります。大きなオブジェクトが .NET マネージ ヒープ内に作成されると、ヒープ内の特別な部分に割り当てられます。大きなオブジェクトを移動することによるオーバーヘッドは、ヒープ内のこの部分を整理することで得られるパフォーマンスの向上を上回ります。

Compact アルゴリズムは、メモリの再割り当て速度を上げるだけでなく、新しく割り当てられたオブジェクトがヒープ内にコンパクトに配置されていればキャッシュ パフォーマンスも向上します。これは、一緒に割り当てられたオブジェクトは一緒に使用されることが多いため (プログラム ローカリティの原則)、プログラムに連続した空のメモリ領域を提供することが重要だからです。 #p#

2. 世代

世代の年齢とは、ヒープ内のオブジェクトをその存在時間に応じて世代に分割することを意味します。最も短いオブジェクトは世代 0 にあり、最も長いオブジェクトは世代 2 にあります。世代 2 のオブジェクトは、多くの場合、より大きくなります。世代のレベルはフレームワークのバージョンに関連しており、GC.MaxGeneration を呼び出すことによって取得できます。

通常、GC は最近割り当てられたオブジェクト (世代 0) の収集を優先します。これは、オペレーティング システムの従来のメモリ ページング アルゴリズムである「最近最も使用されていない」アルゴリズムとまったく同じです。ただし、これは GC が最近割り当てられたオブジェクトのみを収集するという意味ではありません。通常、.Net GC は、オブジェクトの有効期間の長さに応じてヒープ領域を 3 つの世代に分割します。新しく割り当てられたオブジェクトは世代 0 (世代 0 の最大長は通常 256K) にあり、アドレス順に割り当てられ、通常は何らかのローカル変数です。世代 1 (世代 1 の最大長は通常 2 MB) は、世代 0 のガベージ コレクション後もメモリ内に残っているオブジェクトで、通常はフォーム、ボタンなどのオブジェクトです。世代 2 は、数回のガベージ コレクション後もメモリ内に残っているオブジェクトで、通常は何らかのアプリケーション オブジェクトです。

メモリが不足している場合 (たとえば、Generation 0 オブジェクトがいっぱいの場合)、GC が実行エンジン (CLR) に呼び出され、Generation 0 領域のマーク付け、圧縮、リサイクルが開始されます。これには通常 1 ミリ秒もかかりません。リサイクル後もメモリがまだ逼迫している場合、GC は第 1 世代 (リサイクル操作は通常 10 ミリ秒未満で完了します) と第 2 世代のリサイクルを続行します。もちろん、GC が世代 0、1、2 の順序でガベージを収集しないこともあります。これは、実行時の状況、または手動で GC.Collect(i) を呼び出してリサイクルする世代を指定することに依存します。 2 番目の世代がリサイクルされた後もメモリが不足している場合は、システムは OutOfMemoryException をスローします。複数の GC の後も世代 0 のオブジェクトがまだ存在する場合は、世代 1 に移動されます。同様に、第 1 世代と第 2 世代も同じロジックに従って動作します。

ここで、GC ヒープの世代数と容量は可変であることにも言及する必要があります (これは「ポリシー エンジン」によって制御されます。「ポリシー エンジン」については、2 番目のセクションで説明します)。Windbg と組み合わせた次のコードで、この問題を説明できます。次のコードでは、ボタン「button1」をクリックしてメモリを継続的に割り当て、オブジェクト「a」の世代年齢を取得し、フォームが読み込まれたときに「a」の世代年齢も取得できます。

  1. パブリック部分クラス Form1 : Form
  2. {
  3. プライベート文字列a =新しい文字列 ('a',1);
  4. パブリックForm1()
  5. {
  6. コンポーネントを初期化します。
  7. }
  8. プライベート void button1_Click(オブジェクト送信者、EventArgs e)
  9. {
  10.              a =新しい文字列 ('a'、900000);
  11.              label1.Text = GC .GetGeneration(a).ToString();
  12. }
  13. プライベート void Form1_Load(オブジェクト送信者、EventArgs e)
  14. {
  15.              label1.Text = GC .GetGeneration(a).ToString();
  16. }
  17. }

プログラムがロードされた直後は、「a」の世代年齢は世代 0 です。windbg を通じて、次の情報も取得されます。

GC ヒープが 2 つのセグメントと 3 つの世代に分かれていることがわかります。各世代の開始アドレス間の小数点の差は 12 です。「button1」ボタンを数回クリックすると、「a」の世代年齢が第 2 世代にアップグレードされます。windbg を通じて、次の情報を取得します。

ここで注目すべき重要な点は、各世代の開始点(世代 x の開始点)の 10 進アドレスの差が 12 ではなくなったことです。世代 0 と世代 1 の差は 98904、世代 1 と世代 2 の差は 107908 です。これは、プログラムの実行に伴って世代のサイズが変わり、GC ヒープのサイズも変わることを示しています。

元のタイトル: .Net Discovery Series 3 - .Net ガベージ コレクション メカニズムの詳細な理解 (パート 1)

オリジナルリンク: http://www.cnblogs.com/isline/archive/2009/03/03/1402350.html

【編集者のおすすめ】

  1. .NET ガベージ コレクションのパフォーマンスを向上させるいくつかの方法の簡単な分析
  2. .Net Framework ガベージ コレクション固有のアルゴリズムの詳細な説明
  3. .NET Framework メモリ回復操作の詳細が公開されました
  4. .NET Framework 4.0 の機能の詳細説明
  5. .NET Framework 4.0 の Lazy について少し

<<:  Pythonアルゴリズムの正しい実装の紹介

>>:  Microsoft IE8 の「ランダム ブラウザ選択」アルゴリズムはランダムではなく、不利な状況に陥っています。

ブログ    
ブログ    
ブログ    

推薦する

機械学習研究開発プラットフォームの選択

機械学習は現在隆盛を極めていますが、機械学習を学習・研究し、実稼働環境で活用したい場合には、プラット...

...

機械学習によるよりスマートなユーティリティ管理

エネルギー、ガス、水道、廃棄物管理などの公共事業では、すでにインフラストラクチャを最適化し、需要と供...

2024年に誰もが備えるべき5つのテクノロジートレンド

機械知能、現実と仮想の境界線の曖昧化、そしてインターネットの継続的な進化は、私たちの生活に根本的な影...

...

科学者らが磁場を使ってバイオニックロボットの動きを制御する新たな解決策を発表

科学者は長い間ロボット工学の分野に興味を持っており、最近のバイオニックソフトロボットはロボット工学の...

中国初!最も人気のあるMoE大型モデルアプリがここにあります。無料でダウンロードでき、誰でもプレイできます。

MoE(Mixed of Experts)モデルは最近とても人気があるので、詳しく紹介する必要はな...

...

...

LLM評価にArthur Benchを使用する方法を学ぶ

こんにちは、皆さん。私は Luga です。今日は、人工知能 (AI) エコシステムに関連するテクノロ...

...

2021 年にグラフ機械学習にはどのような新たなブレークスルーがあるでしょうか?マギル大学のポスドク研究員が分野の動向を整理

[[443041]]今年ももうすぐ終わり、あと3日で2021年も終わりです。さまざまなAI分野でも...

データセンター市場はAIの爆発的な増加に向けて準備を整えている

最近、人工知能分野での成功事例や投資発表が急増し、ビジネス界の注目と関心を集めています。最近の AI...

AI は無限であり、あなたの声によって動かされます。マイクロソフトは慈善団体や業界のパートナーと協力し、テクノロジーで愛を育むお手伝いをします。

12月2日、マイクロソフトと周迅のAI音声紅丹丹慈善プロジェクトの発起人である魯音源文化伝承社は、...