.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 の「ランダム ブラウザ選択」アルゴリズムはランダムではなく、不利な状況に陥っています。

ブログ    
ブログ    

推薦する

早く見て!無料の機械学習コーストップ10

この記事では機械学習入門、ディープラーニング、自然言語処理などを網羅した関連講座10選を紹介します。...

ヘルスケアにおけるAIの加速

[[407769]]ヘルスケア業界における人工知能の活用AI技術が進歩するにつれて、その応用も拡大し...

より良い生活を実現するために、Hongheの2019年の新製品が発売されました

最近、「Honhe AI、生活をより良くする--Honheグループ2019年新製品発表会」が成都で開...

2020 年の企業向け最高の AI プラットフォーム

企業は長年にわたり、業務と分析を手作業で処理してきましたが、その結果、人件費と事務処理が増加し、最適...

AIをめぐる世界的な競争でリードしているのは中国、米国、それともヨーロッパか

現在、世界中でAI関連企業に多額の投資が流入しており、トップ研究機関の科学者が毎週、さまざまなAIア...

...

デジタルツインの登場: 医薬品開発における今後の革命

51年前、アポロ13号が宇宙に打ち上げられました。打ち上げ直後、宇宙船は大きな爆発に遭遇した。宇宙船...

...

中国のAI特許申請数が米国を上回った!我が国の最新の5Gの成果:世界をリードする技術

この記事はLeiphone.comから転載したものです。転載する場合は、Leiphone.com公式...

AIビジョンを取り入れることで、ガソリンスタンドは非常に「スマート」になることができます

[[354264]]石油貯蔵所、ガソリンスタンド、石油荷降ろしトラックには大量の完成燃料が保管され...

2020年世界人工知能会議が開催されます! AI が人間の言語の高度な能力をいかにして習得するかをご覧ください。

2020年7月9日、2020年世界人工知能大会(WAIC)クラウドサミットが正式に開幕しました。I...

...

...

AMU-Botロボット:作物の間を移動しながら除草する

手作業による除草は時間がかかり、労力もかかりますが、除草剤を散布するのは決して環境に優しくありません...

RPAは人工知能の究極の発展方向でしょうか?

ロボティック・プロセス・オートメーション (RPA) は、単調で反復的なタスクを排除するのでしょうか...