記事ディレクトリ
世代別コレクション理論
現在の商用仮想マシン用のガベージ コレクターのほとんどは、次の 2 つの世代仮説に基づく経験則である「世代コレクション」理論 [1] に従って設計されています。
-
弱い世代仮説: ほとんどのオブジェクトは一時的です。
-
強力な世代別仮説 (強力な世代別仮説): ガベージ コレクション プロセスで生き残るオブジェクトが多ければ多いほど、消滅するのが難しくなります。
世代別コレクション理論を現在の商用 Java 仮想マシンに適用すると、設計者は通常、Java ヒープを少なくとも 2 つの領域 (若い世代と古い世代) に分割します [2]。名前が示すように、新しい世代では、ガベージが収集されるたびに多数のオブジェクトが失われることが判明し、収集のたびに生き残った少数のオブジェクトが徐々に古い世代に昇格して保管されます。
世代理論については、古い世代が新しい世代を参照する場合があり、オブジェクトをリサイクルする際の判定にパフォーマンスに影響するため、以下の仮定も行う必要があります。
- 世代間参照仮説 (世代間参照仮説): 世代間の参照は、同世代の参照と比較すると非常に少数にすぎません。
上記の結論は、最初の 2 つの仮説の論理的推論に基づく暗黙の推論から導き出すことができます。相互参照関係を持つ 2 つのオブジェクトは、同時に生きるか死ぬ傾向があるはずです。
一般的な世代別のコレクション名詞をいくつか示します
-
部分コレクション (部分 GC) : Java ヒープ全体を完全に収集することが目的ではないガベージ コレクションを指します。Java ヒープは次のように分割されます。
-
マイナー GC/ヤング GC : 新しい世代のみを目的とするガベージ コレクションを指します。
-
旧世代コレクション(Major GC/Old GC) : 旧世代のみを対象としたガベージコレクションを指します。現時点では、CMS コレクターのみが古い世代を個別に収集する動作を備えています。
-
混合コレクション (Mixed GC) : 新しい世代全体と古い世代の一部を収集することを目的としたガベージ コレクションを指します。現時点では、G1 コレクターのみがこの動作を示します。
-
-
ヒープ全体コレクション (Full GC) : Java ヒープおよびメソッド領域全体を収集するガベージ コレクション。
マークスイープアルゴリズム
マーク アンド スイープ アルゴリズム (マーク アンド スイープ アルゴリズム) は、参照されなくなったオブジェクトを識別して解放し、メモリ領域を再利用するために使用される古典的なガベージ コレクション アルゴリズムです。これは、マークとスイープの 2 つの主要なフェーズで構成されます。
マーク アンド スイープ アルゴリズムがどのように機能するかは次のとおりです。
- マーク(Mark)ステージ:
- ルート オブジェクト (通常はプログラムのエントリ ポイントまたはグローバル変数) から開始して、オブジェクト グラフ全体を走査し、ルート オブジェクトからアクセスできるすべてのオブジェクトをマークします。
- この段階では、マークされたオブジェクトは通常、マーク ビットでマークされるか、「マークされた」セットに追加されて、それらがアクティブなオブジェクトであり、まだ参照されていることを示します。
- スイープフェーズ:
- クリーンアップ フェーズ中に、ガベージ コレクターはヒープ メモリ全体を走査し、マークされていないオブジェクト、つまり参照されなくなったオブジェクトをすべて見つけます。
- マークのないオブジェクトはガベージとみなされ、ガベージ コレクターはそのメモリ領域を将来のオブジェクト割り当てのための空き領域としてマークします。
- クリア後は、マークされたオブジェクトのみがヒープ メモリに残り、マークされていないオブジェクトのメモリは解放されます。
上記で注意すべき点は、マークされたオブジェクトは、リサイクルする必要があるすべてのオブジェクトである可能性があるということです。マークが完了すると、マークされたすべてのオブジェクトが均一にリサイクルされるか、または、残っているオブジェクトがマークされ、マークされていないすべてのオブジェクトがリサイクルされます。一律リサイクルです。
以下はマーククリアアルゴリズムの概略図です。
マーク アンド スイープ アルゴリズムの利点は、参照されなくなったオブジェクトを再利用できることですが、いくつかの欠点もあります。
- 断片化の問題: マークスイープ アルゴリズムはメモリ内に不連続な空きブロックを残し、メモリの断片化の問題を引き起こす可能性があります。これにより、大きなオブジェクトを割り当てるときにスペース不足の問題が発生するリスクが高まります。
- 効率の問題: マーククリア アルゴリズムは、ヒープ メモリ全体を 2 回走査する必要があります。1 回目はマーキングで、もう 1 回はクリアです。これにより、特にクリーンアップ段階でパフォーマンスのオーバーヘッドが追加されます。
- 停止問題: クリーンアップ操作を実行するにはヒープ メモリ全体が一定の状態にある必要があるため、マーク アンド スイープ アルゴリズムはクリーンアップ フェーズ中にアプリケーションの実行を停止する必要があります。これにより、ガベージ コレクション中にアプリケーションが停止し、ユーザー エクスペリエンスに影響を与える可能性があります。
マークコピーアルゴリズム
マーク アンド コピー アルゴリズム (Mark and Copy Algorithm) は、マーク クリア アルゴリズムで発生するメモリの断片化の問題を解決するガベージ コレクションのアルゴリズムです。マークコピーアルゴリズムは主に若い世代(Young Generation)のガベージコレクションに使用され、通常はマーク(Mark)とコピー(Copy)の2段階に分かれています。
マークアンドコピー アルゴリズムがどのように機能するかは次のとおりです。
-
マーク(Mark)ステージ:
- ルート オブジェクト (通常はプログラムまたはグローバル変数のエントリ ポイント) から開始して、オブジェクト グラフ全体が走査され、ルート オブジェクトから到達できるすべてのオブジェクトがマークされ、これらのオブジェクトはアクティブ オブジェクトとみなされます。
- この段階では、マークされたオブジェクトは通常、マーク ビットでマークされるか、「マークされた」セットに追加されて、それらがアクティブなオブジェクトであり、まだ参照されていることを示します。
-
コピー(コピー)フェーズ:
- コピー フェーズ中に、ガベージ コレクターは、ライブ オブジェクトとしてマークされたすべてのオブジェクトを、ある領域 (通常、「From」または「Eden」領域と呼ばれます) から別の領域 (通常、「To」または「Survivor」領域と呼ばれます) にコピーします。
- コピー後、コピーされたすべてのオブジェクトは断片化することなく連続して配置され、「From」領域は空になります。
-
クリーンアップ段階:
- コピーされるオブジェクトはクリーンアップ段階では不要になるため、「From」領域全体を空にして、将来のオブジェクト割り当てのための新しい空き領域にすることができます。
概略図は次のとおりです
マークコピー アルゴリズムの主な利点は、メモリの断片化の問題を効果的に解決できることです。コピーされたオブジェクトはきれいにまとめられているため、「From」領域は空になり、メモリの断片化は発生しません。これにより、メモリ使用率が向上し、大きなオブジェクトを割り当てるときに発生する可能性のあるスペース不足の問題が軽減されます。欠点はスペースの無駄であることです。
マーク コピー アルゴリズムは、若い世代では主にガベージ コレクションに使用されますが、古い世代では通常、マーク スイープ アルゴリズムやマーク コンパクト アルゴリズムなどの他のアルゴリズムが使用されます。これらのさまざまなガベージ コレクション アルゴリズムを組み合わせて、最新の Java 仮想マシンで複雑なガベージ コレクション戦略を形成し、メモリ管理の効率とパフォーマンスを向上させます。
マーク照合アルゴリズム
マーク アンド コンパクト アルゴリズム (Mark and Compact Algorithm) は、ガベージ コレクションのアルゴリズムで、通常は旧世代 (Old Generation) でのメモリ回復に使用されます。これはマーククリア アルゴリズムの改良版であり、主にマーククリア アルゴリズムによって発生する可能性のあるメモリの断片化の問題を解決します。
マーククリアアルゴリズムと比較して、ソートプロセスが 1 つだけ多い
仕上げ(コンパクト)ステージ:
- 整頓段階では、ガベージ コレクターは、ライブとしてマークされたすべてのオブジェクトを一方の端に移動し、連続して整列させます。同時に、マークされていない/マークされたオブジェクトは不要とみなされ、メモリ空間が解放されます。
- 並べ替え後、メモリ内のアクティブ オブジェクトは断片化することなくよりコンパクトになり、メモリ使用率が向上します。
概略図は次のとおりです