ホームページ >Java >&#&チュートリアル >java -- ガベージ コレクション メカニズムの詳細な説明

java -- ガベージ コレクション メカニズムの詳細な説明

巴扎黑
巴扎黑オリジナル
2017-07-18 18:15:431571ブラウズ

概要

1. ガベージ

JVM ガベージ コレクションは、スレッドの開始時にスタックにスペースが割り当てられ、スレッドの終了時にスペースが自動的に解放されるため、主にヒープ内のガベージをターゲットとします。モニタリングは必要ありません。メソッド領域には主にクラス情報、静的変数、定数が保存されます。これらは通常、プログラムの実行中に有効であり、リサイクルする必要のあるオブジェクトはありません。

ガベージとは、スレッドからアクセスできないオブジェクトを指します。オブジェクトは、スレッドに表示され、スレッドからアクセスできる場合にのみ使用できます。また、単に参照のないオブジェクトとして理解することもできます。厳密に言えば、オブジェクトへの参照がない表現はゴミの範囲を狭めます。たとえば、循環参照では、オブジェクト A は別のオブジェクト B を参照し、オブジェクト B は A を参照します。A と B の間には参照関係のみが存在します。この 2 つの間に、A または B を参照する外部オブジェクトがない場合、A と B はプログラムの実行に含めることができません。つまり、どのスレッドからもアクセスできず、それらは役に立たないオブジェクトになります。ゴミの定義、それらはもはやゴミではありません 使用されたオブジェクトはゴミであり、A と B は当然ゴミに属します。

ゴミは役に立たないオブジェクトとも呼ばれ、ゴミではないものは生きたオブジェクトと呼ばれることもあります。

2. メモリリーク

無駄なオブジェクトがメモリを占有し続け、メモリの無駄が発生する現象をメモリリークといいます。メモリ リークの根本的な原因は、次のコードのように、寿命の長いオブジェクトが使用後も寿命の短いオブジェクトへの参照を保持していることです。

オブジェクトはメソッド内で作成されます。オブジェクトの作成の目的は、オブジェクト内のメソッド doSome にアクセスすることだけです。この時点では、オブジェクトにはアクセスできません。オブジェクトには参照があるため、オブジェクトはガベージとは見なされませんが、オブジェクトは役に立たないオブジェクトになっているため、ガベージ コレクターがオブジェクトによって占有されているメモリ領域を再利用できるように逆参照する必要があります。 obj=null;」は逆参照します。

3. メモリのリサイクル

ガベージ コレクターはオブジェクトをリサイクルするのではなく、不要なオブジェクトによって占有されているメモリ領域を再利用できるようにします。

4. メモリの断片化

図に示すように、メモリの割り当てとリサイクルのプロセス中に生成される小さな不連続な空き領域:

リサイクルを待機している領域が原因リサイクルが完了すると、使用可能なスペースが使用済みスペースに応じて独立した小さなユニットに分割されます。これらのユニットはサイズが小さいため、大きなデータを保存するために追加のスペースを空ける必要があり、無駄が発生します。記憶の。

ガベージを判定するための 2 つのアルゴリズム

1. 参照カウント アルゴリズム

オブジェクトが作成されると、変数がオブジェクトを参照するたびに参照カウンターが増分されます。 1 になり、変数が参照を解放すると、カウンタは 1 ずつ減少します。カウンタが 0 の場合は、オブジェクトがそのオブジェクトを参照していないことを意味し、そのオブジェクトはガベージになります。

参照カウント アルゴリズムの本質的な欠陥は、循環参照の問題を解決できないことです。つまり、サイクルによって参照される 2 つのオブジェクトが使用されなくなったとしても、それらは依然として使用可能なオブジェクトとみなされ、使用されなくなります。ガベージコレクターによってリサイクルされます。 JVM ガベージ コレクション メカニズムでは、このアルゴリズムは使用されませんが、次の到達可能性分析アルゴリズムが使用されます。

2. 到達可能性分析アルゴリズム

到達可能性分析アルゴリズムは、追跡を使用してオブジェクトが生きているかどうかを判断します。追跡可能または到達不可能なオブジェクトは生きているオブジェクトです。役に立たないオブジェクトです。追跡の開始点は、現在アクセスされているオブジェクトです。このオブジェクトから開始して、そのオブジェクトによって参照されているオブジェクトを見つけて、参照チェーン上にないオブジェクトを順番にループします。スレッドによって使用されており、ゴミです。以下の図に示すように、左側に参照チェーンが形成されています。右側のオブジェクトは相互に参照関係を持っていますが、チェーン上のすべてのオブジェクトはスレッドの参照チェーンの外にあります。 、したがって、それらは役に立たないオブジェクトです。

この種の分析は静的ではなく動的であり、オブジェクト参照関係の変化に応じて変化します。

オブジェクトストレージの 3 つの区分

異なるオブジェクトには異なるライフサイクルがあります。タイムリーにメモリをリサイクルするために、ライフサイクルの短いオブジェクトに対してガベージコレクション操作が頻繁に実行されますが、ライフサイクルの長いオブジェクトは比較的実行されます。ガベージ コレクション スキャンの数が少ないため、オーバーヘッドを節約し、ガベージ コレクションの数を減らすために、ライフ サイクルの異なるオブジェクトがメモリの異なる領域に保存され、異なるガベージ コレクション戦略が使用されます。採用することができます。

JVM は、オブジェクトストレージスペースを新世代、旧世代、永続世代の 3 つの領域に分割します。

1. 新しい世代

新しい世代は、ライフサイクルの短いオブジェクトを迅速にリサイクルするために確立されます。新しく生成されたオブジェクトはすべて、最初に新しい世代に配置されます。新世代はeden、from survivor、to survivorの3つのパートに分かれており、スペース比は8:1:1です。

新しく作成されたオブジェクトは最初に eden に配置され、eden 領域がいっぱいになった後、生き残ったオブジェクトが from survivor 領域に転送されます。がいっぱいの場合、生存オブジェクトは生存者に転送され、生存者領域がいっぱいになると、生存オブジェクトは古い世代に昇格されます。

JVM は、若い世代のオブジェクトに対して gc を頻繁に実行し、ほとんどのオブジェクトが若い世代でリサイクルされ、少数のオブジェクトが古い世代に入ります。

2. 古い世代

古い世代のオブジェクトは、ライフサイクルが長く、比較的安定しているため、GC 操作の回数が少なくなります。

3. 永続生成

永続生成は、クラス情報、静的変数、定数を格納する領域であり、通常はガベージ コレクターの処理を必要としません。

4つのガベージコレクションアルゴリズム

ガベージコレクションアルゴリズムは、ガベージ確認後の実際の収集に使用されるアルゴリズムです。

1. マーククリアメソッド

。オブジェクトを削除し、オブジェクトが占有しているメモリ空間を再利用するとメモリの断片化が発生するため、このアルゴリズムは基本的には使用されません。

2. コピー アルゴリズム

は、ガベージ コレクション中にメモリ空間を複数の領域に分割し、1 つの領域に残っているすべてのオブジェクトを別の領域にコピーし、メモリの断片化が発生しないようにします。 。このアルゴリズムは、新世代のガベージ コレクションで、eden 領域から from survivor 領域にコピーし、次に to survivor 領域にコピーするときに使用されます。生き残るオブジェクトが少ないため、コピー中に使用されるスペースが少なくなります。

3. マーキング整理アルゴリズム

まず、消去する必要があるオブジェクトをマークし、残っているすべてのオブジェクトを一方の端に移動し、次に不要なオブジェクトをすべて消去します。新しい世代とは異なり、古い世代では各 GC 後に生き残るオブジェクトが増え、コピー アルゴリズムは大量のメモリを消費します。「マーク整理」アルゴリズムはメモリの断片化を引き起こすことなくメモリを節約します。

5 ガベージコレクションのタイミング

世代が異なると、GC メカニズムも異なります: スカベンジ GC とフル GC。

新世代の eden 領域がいっぱいで、新しく生成されたオブジェクトがスペースの適用に失敗した場合、Scavenge GC がトリガーされ、eden 領域に対して gc 操作が実行され、不要なオブジェクトが削除され、スペースが確保されます。 Scavenge GC は新しい世代でのみ動作します。

古い世代または永続世代がいっぱいの場合、または System.gc() メソッドが明示的に呼び出された場合、フル GC がトリガーされ、すべてのオブジェクト記憶領域に対して gc が実行されます。リソースの消費量が多くなります。フル GC の頻度を低くする必要があります。

その他の 6 つのメソッド

1. System.gc()

は、ガベージ コレクターを開始するように JVM に指示するため、すぐには開始できない場合があります。コントロールされる。また、は大量のリソースを消費するため、通常は明示的に呼び出さないでください。

2.finalize()

オブジェクトスコープのメソッド。 JVM がオブジェクトにアクセスできないことを確認した後に呼び出されます。呼び出すことができるのは 1 回のみで、通常は接続リソースを解放するために使用されます。このメソッドの実行中にオブジェクトが再びアクセスされる可能性があるため、ガベージ コレクターは、このメソッドが呼び出された後、オブジェクトが占有している領域をすぐに再利用するのではなく、オブジェクトが占有している領域を再利用するのは、オブジェクトは次の gc スペースではまだアクセスできません。

GCオーバーヘッドを削減する7つの対策

  1. 静的変数のライフサイクルはアプリケーションのライフサイクルと同じであるため、静的変数は長期間使用されなかったとしても、静的変数の使用は避けてください。メモリ空間を占有します。

  2. OutputStreamInputStreamConnectionSocket などのリソース接続は、使用後すぐに閉じ、リソースを適時に解放する必要があります。

  3. System.gc() を明示的に呼び出さないようにしてください。このメソッドは負荷の高いフル GC をトリガーする可能性があります。

  4. メソッドの実行後、一時変数はゴミになるため、一時変数の使用を減らします。一時変数が大量にあると gc の数が増加し、システムの消費量が増加します。

  5. オブジェクト参照が完了したら、時間内に参照を解放して、メモリ空間を再利用します。

  6. 可変オブジェクトを使用し、不変オブジェクトの使用数を減らすようにしてください。

  7. 基本型変数は、対応するラッパー クラスよりも占有するリソースがはるかに少ないため、対応するラッパー クラスの代わりに基本型変数を使用するようにしてください。

  8. オブジェクトを散在的に作成および削除します。オブジェクトをまとめて作成すると大量のスペースが必要となり、フル GC がトリガーされ、システム消費量が即座に増加する可能性があるためです。オブジェクトを集中的に削除すると、不要なオブジェクトが一瞬で大量に出現し、フル GC が発生する可能性があります。

参照:

以上がjava -- ガベージ コレクション メカニズムの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:Javaの概要と特徴次の記事:Javaの概要と特徴