1024 連休おめでとうございます! ——Java ガベージ コレクション メカニズム

Java ガベージ コレクション メカニズム

ガベージ コレクションを実行するには、最も重要な質問は、誰がガベージであるかを判断することです。

日常生活で考えてみると、頻繁に使用しないものはゴミと言えます。同じことがJava にも当てはまり
、オブジェクトが参照できなくなった場合、そのオブジェクトはガベージであるため、リサイクルする必要があります。

この考えに基づいて、参照カウントを使用してガベージを判断することを簡単に考えることができます。オブジェクトが参照されると 1 ずつインクリメントされ、逆参照されると 1 ずつデクリメントされるため、参照カウントが 0 かどうかでオブジェクトがゴミであるかどうかを判断できます。この方法は一般に「リファレンスカウント法」と呼ばれています。

上記の方法は簡単ではありますが、循環参照という致命的な問題があります。

A は B を参照し、B は C を参照し、C は A を参照します。それぞれの参照カウントは
1 です。ただし、これら 3 つのオブジェクトは他のオブジェクトから参照されることはなく、それら自体が相互に参照するだけです。ゴミ判定の観点から見ると、確かにこの3つは他のオブジェクトから参照されていませんが、この時点での参照数はゼロではありません。これは参照カウントの循環参照問題です。

現在の Java 仮想マシンは、GC ルート トレーシング アルゴリズムを使用してガベージ オブジェクトを特定します。一般的なプロセスは次のとおりです。GC
ルートから始まり、到達可能なすべてのオブジェクトは生きたオブジェクトであり、到達できないオブジェクトはすべてガベージです。

ここで最も重要なのは GC Root コレクションであることがわかります。実際、GC Root は
アクティブな参照のコレクションです。ただし、このコレクションは一般的なオブジェクト コレクションとは異なり、特別に選択されており、通常は次のものが含まれます。

現在ロードされているすべての Java クラス、Java クラスの参照型静的変数、Java クラスのランタイム定数プール内の参照型定数、VM の
一部の静的データ構造内の GC ヒープ内のオブジェクトへの参照など。簡単に言うと、GCルートは
、生き残ることが保証されている、慎重に選択されたアクティブな引用のセットです。そうすれば、これらの参照によって拡張されたオブジェクトは自然に存続します。

ガベージコレクションはどうやって行うのですか?

この時点で、ガベージとは何か、そして JVM がガベージ オブジェクトをどのように判断するかについて理解しました。では、ガベージ オブジェクトを特定した後、
JVM はどのようにガベージ コレクションを実行するのでしょうか? それが私たちが次に話すことです: ガベージ コレクションを行うにはどうすればよいでしょうか?

簡単に言うと、ガベージ コレクション アルゴリズムには、マーク アンド スイープ アルゴリズム、コピー アルゴリズム、およびマーク圧縮アルゴリズムの 3 つがあります。

マークアンドスイープアルゴリズム。名前からわかるように、マーキングフェーズとクリアフェーズの 2 つのフェーズに分かれています。実現可能な実装は、
マーキング フェーズ中に GC ルートによってトリガーされた、到達可能なすべてのオブジェクトをマークすることです。現時点では、マークされていないオブジェクトはすべてガベージ オブジェクトです。次に、クリーンアップ フェーズで、マークされていないすべてのオブジェクトがクリアされます。マーク アンド スイープ アルゴリズムの最大の問題は、空間の断片化です。空間フラグメントが多すぎると、メモリ空間に不連続性が生じます。大きなオブジェクトを不連続空間に割り当てることもできますが、効率は連続メモリ空間よりも低くなります。

レプリケーションアルゴリズム。コピー アルゴリズムの中心的な考え方は、元のメモリ空間を 2 つのブロックに分割し、一度に 1 つのブロックのみを使用することであり、ガベージ コレクション中に、使用されているメモリ内に残っているオブジェクトが未使用のメモリ ブロックにコピーされます。次に、使用されているメモリ ブロック内のすべてのオブジェクトをクリアし、2 つのメモリ ブロックの役割を交換してガベージ コレクションを完了します。このアルゴリズムの欠点は、メモリ スペースが半分になり、メモリ スペースが大幅に無駄になることです。

フラグ圧縮アルゴリズム。マーク圧縮アルゴリズムは、マーククリアアルゴリズムの最適化バージョンであると言えますが、マーククリアアルゴリズムも 2 つの段階、つまりマーク決済段階と圧縮段階を経る必要があります。マーキング フェーズでは、
すべてのオブジェクトが GC ルート参照コレクションからトリガーされます。圧縮フェーズでは、残っているすべてのオブジェクトがメモリの片側で圧縮され、境界の外側のすべてのスペースがクリアされます。

これら 3 つのアルゴリズムを比較すると、それぞれに独自の長所と短所があることがわかります。

マーク アンド クリア アルゴリズムではメモリの断片化が発生しますが、あまりにも多くのオブジェクトを移動する必要がないため、多くのオブジェクトが残っている状況により適しています。コピー アルゴリズムではメモリ スペースを半分にし、生き残ったオブジェクトを移動する必要がありますが、クリーニング後にスペースの断片化が発生しないため、生き残ったオブジェクトが比較的少ない状況に適しています。マーク圧縮アルゴリズムは、マーク クリア アルゴリズムの最適化されたバージョンであり、スペースの断片化を軽減します。

世代的な考え方

想像してみてください。アルゴリズムを単独で使用した場合、最終的なガベージ コレクションの効率はあまり良くありません。実際、JVM
仮想マシンの作成者もそう考え、実際のガベージ コレクション アルゴリズムに世代別アルゴリズムを採用しました。

いわゆる世代別アルゴリズムでは、
JVM メモリの異なるメモリ領域に応じて異なるガベージ コレクション アルゴリズムが使用されます。たとえば、生き残っているオブジェクトがほとんどない新世代領域の場合は、レプリケーション アルゴリズムの方が適しています。この方法では、ガベージ コレクションを完了するためにコピーする必要があるオブジェクトの数は少なく、メモリの断片化は発生しません。旧世代のように多くのオブジェクトが残っている領域では、あまりにも多くのメモリ オブジェクトを移動する必要がないように、マーク圧縮アルゴリズムまたはマーク クリア アルゴリズムを使用する方が適しています。

世代別アルゴリズムを使用する代わりに、古い世代でレプリケーション アルゴリズムが使用された場合を想像してください。極端な場合には、旧世代のオブジェクトの生存率が 100% に達することもあるため、非常に多くのオブジェクトを別のメモリ領域にコピーする必要があり、膨大な作業負荷になります。

ここでは、新世代で採用されているガベージコレクションアルゴリズムについて詳しく説明します。上で述べたように、新世代は生き残るオブジェクトがほとんどないという特徴があり、レプリケーション アルゴリズムに適しています。レプリケーション アルゴリズムの最も単純な実装の 1 つは、メモリの半分を使用し、残りの半分を予約することです。しかし実際には、実際の
JVM の新世代分割では、メモリが 2 つの等しい部分に分割されていないことがわかっています。代わりに、Eden エリア、from エリア、to エリアの 3 つのエリアに分かれています。では、なぜ JVM は
最終的に 2 つのメモリ ブロックに 50% ずつ分割するのではなく、この形式を採用するのでしょうか?

この質問に答えるには、まず新世代オブジェクトの特性を深く理解する必要があります。IBM の調査によると、新世代のオブジェクトの 98% は
存続し、消滅するため、メモリ空間を 1:1 の比率に従って分割する必要はありません。したがって、HotSpot 仮想マシンでは、JVM は
メモリをより大きな Eden スペースと 2 つの小さな Survivor スペースに分割し、それらのサイズ比は 8:1:1 になります。リサイクルするときは、Eden と Survivor に残っているオブジェクトを別の Survivor スペースに一度にコピーし、最後に Eden と使用したばかりの Eden スペースをクリーンアップします。

このようにして、メモリ領域の使用率は 90% に達し、領域の 10% のみが無駄になります。メモリを 2 つのメモリに均等に分割した場合、メモリ使用率はわずか
50% となり、2 つの使用率の差はほぼ 2 倍になります。

パーティションの考え方

世代別の考え方では、オブジェクトのライフサイクルの長さに応じてオブジェクトを 2 つの部分 (新世代と旧世代) に分割しますが、実際には
JVM には分割の考え方があり、ヒープ領域全体を異なる連続した小さな領域に分割するというものです。間隔。

それぞれの小さな間隔は独立して使用され、独立してリサイクルされます。このアルゴリズムの利点は、一度にリサイクルされる間隔の数を制御でき、GC 時間をより適切に制御できることです。

この時点で、
最初のガベージとは何か、後でガベージを判断する方法、ガベージをリサイクルする方法、そしてガベージ コレクションの 2 つの重要な概念である世代的思考とパーティショニング的思考に至るまで、JVM ガベージ コレクションのすべてが基本的に明確になりました。 。このような文脈を通じて、ガベージ コレクションの全体的な概要を理解します。次の章では、詳細について説明します。

おすすめ

転載: blog.csdn.net/Turniper/article/details/120937657