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

ブログ    

推薦する

米研究機関:中国は2030年までにAI研究で世界をリードすると予想

アメリカのテクノロジーメディアGeekWireによると、米国シアトルのアレン人工知能研究所(AI2)...

教師なし機械学習技術は金融セキュリティの懸念を解決できる

「テクノロジーがなければ、金融は存在しない。」モバイルインターネット時代の到来により、テクノロジーや...

...

Midjourney はテキストを生成できます。 V6バージョンの5つの主要なアップグレードがネットユーザーを驚かせる

Midjourney がメジャーアップデートされ、バージョン V6 がリリースされました!アップデー...

...

中国の博士がCNN全体を視覚化し、各畳み込みとプーリングが明確になった

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

予測分析の 4 つの業界における用途

[[436125]]画像ソース: https://pixabay.com/images/id-602...

北京大学とテンセントは、デザイナーと同じくらいクリエイティブなテキストロゴ生成モデルを提案した。

テキスト ロゴのデザインはデザイナーの創造性と経験に大きく依存しますが、その中でも各テキスト要素のレ...

ローカル AI: スマートフォン時代の低消費電力分析

人工知能にはボトルネック問題があります。これはディープ ニューラル ネットワークに基づいており、数億...

...

DeepMindは大規模なモデルで帰納法と演繹法を学習できるようにし、GPT-4の精度は13.7%向上した。

現在、大規模言語モデル (LLM) は、特にいくつかの例と中間ステップが与えられた場合に、推論タスク...

Nvidia、AIを使った仮想世界のリアルタイムレンダリングを実演

[[251560]] Nvidia は、従来のモデリングやグラフィック レンダリング エンジンではな...

ロボット犬をDIYするにはどれくらいの費用がかかりますか?価格は900ドルと安く、スタンフォード大学が開発し、コードはオープンソースです

たった 900 ドルで四足ロボット犬を DIY できる?スタンフォード学生ロボットクラブの新メンバー...

...