Java仮想マシンオブジェクトの生存判定とガベージコレクションアルゴリズム

Java仮想マシンオブジェクトの生存判定とガベージコレクションアルゴリズム

[[323332]]

この記事では主に、オブジェクトが生きているかどうかを判断する方法を説明し、Java 仮想マシンのガベージ コレクション メカニズムのガベージ コレクション アルゴリズムを示します。

1. 概要

Java プログラマーであれば、GC やガベージコレクションメカニズムなどの用語を多かれ少なかれ聞いたことがあるでしょう。しかし、ゴミのリサイクルとは一体何なのでしょうか?ゴミとは何でしょうか?そして、どのようにリサイクルするのでしょうか?この記事ではその答えを紹介します。

2. ガベージコレクションのメカニズム

ガベージコレクション(英: Garbage Collection、略称 GC)は、コンピュータサイエンスにおける自動メモリ管理メカニズムです。コンピュータ上の動的メモリが不要になった場合は、メモリ用のスペースを確保するために解放する必要があります。このメモリ リソース管理はガベージ コレクションと呼ばれます。

皆様に分かりやすくするために、鮮明な絵を描きました。レストランにはたくさんのテーブル(連続した記憶領域)があり、顧客(オブジェクト)が食事をするためにレストランに来ますが、これらの顧客は非常に社交的です。彼らは食事をした後も立ち去ろうとしないので、レストランのオーナーは彼らを追い出さなければなりません。以前は、この仕事(手動でメモリを解放する)はボスの女性が行っていましたが、現在はロボット(ガベージコレクション機構)が導入され、食事を終えた顧客に退店をお願いしています。

生成: まず第一に、ガベージ コレクションは Java の副産物ではありません。ガベージ コレクションを使用した最も古い言語は、1960 年に作成された Lisp です。ガベージ コレクターの目的は、プログラマーの負担を軽減するとともに、プログラマーがミスを犯す可能性を減らすことです。現在、半世紀以上の開発を経て、ガベージコレクション技術はかなり成熟しており、Python、Erlang、C#、Javaなど、ほとんどの言語がガベージコレクションをサポートしています。

GC とメモリ割り当てを理解する必要があるのはなぜですか?

さまざまなメモリ リークやメモリ オーバーフローのトラブルシューティングが必要な場合、また、システムが高い並行性を実現するためにガベージ コレクションがボトルネックになる場合は、この自動化テクノロジを監視して調整する必要があります。 (夕食後に出発するロボットは万能ではないので、ロボットのパラメータを調整するにはボスの女性も必要です)

3. リサイクルが必要なメモリ

まず、プログラム カウンター、仮想マシン スタック、ローカル メソッド スタックの 3 つの領域はスレッド専用であり、スレッドとともに存続し消滅することが分かっています。スタック フレームは、メソッドが実行されるとスタックにプッシュされ、メソッドが終了するとスタックからポップされます。クラス構造が決まると、基本的に各スタック フレームが占有するメモリの量が決まります。したがって、これらの領域を管理する必要はありません。

次に、Java ヒープとメソッド領域がメモリを共有します。インターフェースには複数の実装クラスがあり、クラスによって必要なメモリの量が異なる場合があります。メソッドの異なるブランチでは、必要なメモリの量も異なる場合があります。システムの実行時に作成する必要があるオブジェクトのみを決定できます。ここでガベージコレクターが動作します。

ガベージコレクション戦略

参照カウント

オブジェクトにカウンターを追加します。どこかから参照されるたびにカウンターは 1 増加し、参照が無効になると 1 減少します。カウンターが 0 に達すると、オブジェクトは使用されなくなり、オブジェクトは死んでしまいます。

参照カウント アルゴリズムは実装が簡単で、効率も優れています。 PythonやRubyなどの言語で使用されます。ただし、主流の Java 仮想マシンでは、オブジェクトへの循環参照の問題を解決できないため、このアルゴリズムを使用してメモリを管理しません。

  1. パブリッククラス ReferenceCounting {
  2. 公共 静的void main(String[] args) {
  3. 犬 dog1 = 新しい犬();
  4. 犬 dog2 = 新しい犬();
  5. // Dog 1 と Dog 2 のオブジェクトは相互参照します
  6. dog1.setSon(dog2);
  7. dog2.setSon(dog1);
  8. // 両方のオブジェクトの参照を null に設定します
  9. dog1 = null ;
  10. dog2 = null ;
  11. システム.gc();
  12. }
  13. }
  14. クラス Dog {
  15. プライベートドッグの息子;
  16. パブリックDog getSon() {
  17. 息子を返す;
  18. }
  19. パブリックvoid setSon(犬の息子) {
  20. this.son = 息子;
  21. }
  22. }

ログを印刷するには、起動パラメータにパラメータ -XX:+PrintGCDetails を設定します。

  1. [GC 7926K->480K(502784K)、0.0023280秒]
  2. [フルGC 480K->316K(502784K)、0.0098820秒]

2 つのオブジェクトは相互に参照しているものの、依然としてリサイクルされているため、ホットスポットは参照カウント アルゴリズムではないことがはっきりとわかります。

ガベージコレクションのトレース

現在、主流の仮想マシンである Java と C# は、オブジェクトが生存しているかどうかを判断するために Tracing ガベージ コレクションを使用しているため、ガベージ コレクションというと、Tracing ガベージ コレクションを思い浮かべます。

基本的な考え方は、いくつかの GC ルート オブジェクトを開始点として定義し、オブジェクトが参照のチェーンを通じてこれらの決定された GC ルート オブジェクトに到達できるかどうかを追跡することです。これらのルート オブジェクトに到達できないオブジェクトは、デッドとみなされます。このアルゴリズムの実際の実装は複雑かつ多岐にわたる可能性があります。

さあ、描き始めましょう。次に、GC Roots、麺の入ったボウル、メニューを準備します。丼が空なのに注文メニューに名前がない人は緑色でマークされます。生存者には、左上の麺類を持っている人、その上の独身でない人、そして家族全員が含まれます。左右の二人は麺が空っぽで注文メニューにも載っていないのに、真ん中の人が参考にしていて、真ん中の人の丼にはたまたま麺が入っている!これは「食べた後に帰らない人を追跡する方法」です。

Java では、次のオブジェクトが GC ルートとして設定されます。

  • 仮想マシンスタック(スタックフレームのローカル変数テーブル)で参照されるオブジェクト:つまり、ローカル変数によって参照されるオブジェクト
  • メソッド領域のクラスの静的属性によって参照されるオブジェクト: public static Dog dog = new Dog();
  • メソッド領域内の定数参照オブジェクト: public static final HashMap map = new HashMap();
  • ネイティブ メソッド スタック JNI で参照されるオブジェクト。

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

周志明教授の『Java 仮想マシンの徹底理解』を読んだことがあるなら、到達可能性分析という用語、つまりここでのトレーシング ガベージ コレクションを必ず知っているでしょう。最初は2つの異なる名前だと思っていましたが、Googleで「到達可能性分析」を検索したところ、ガベージコレクションに関連する情報は見つかりませんでした。 Baidu で見つかった到達可能性分析アルゴリズムは、基本的にすべて、Java 仮想マシン Wikipedia の詳細な理解に基づいています。到達可能性分析の説明は、分散システムがグローバル状態に到達できるかどうかを判断するために使用されます。 Java のガベージ コレクション戦略は、トレース ガベージ コレクションです。そのため、Java 仮想マシンを深く理解するために間違った用語を使用したのではないかと考えています。

脱出分析

エスケープ分析により、オブジェクトがヒープ割り当てからスタック割り当てに移動されるため、ガベージ コレクションの作業が大幅に削減されます。コンパイル時に、関数内で割り当てられたオブジェクトが外部メソッドまたはスレッドによって呼び出されるかどうかを判断します。そうでない場合、オブジェクトはスタックに割り当てられ、ガベージ コレクションの作業が削減されます。

参考文献

JDK 1.2 以降、Java は参照の概念を拡張し、参照を強参照、ソフト参照、弱参照、ファントム参照の 4 種類に分類しました。

  • 強い参照は、"Object obj = new Object()" のように、プログラム コード内でよく見られます。強い参照が存在する限り、ガベージ コレクターは参照されたオブジェクトをリサイクルしません。
  • ソフト参照は、役に立つが必ずしも必要ではないオブジェクトを記述するために使用されます。ソフト参照に関連付けられたオブジェクトの場合、システムでメモリ オーバーフロー例外が発生する前に、これらのオブジェクトは 2 回目のリサイクルのリサイクル範囲に含められます。このリサイクルに十分なメモリがない場合は、メモリ オーバーフロー例外がスローされます。 JDK1.2以降では、ソフト参照を実装するためにSoftReferenceクラスが提供されています。
  • 弱参照は非必須オブジェクトを記述するためにも使用されますが、その強度はソフト参照よりも弱くなります。弱参照に関連付けられたオブジェクトは、次のガベージ コレクションが発生するまでのみ存続できます。ガベージ コレクターが動作している場合、現在のメモリが十分であるかどうかに関係なく、弱参照にのみ関連付けられているオブジェクトが再利用されます。 JDK1.2以降では、弱参照を実装するためにWeakReferenceクラスが提供されています。
  • 仮想参照はゴースト参照またはファントム参照とも呼ばれ、最も弱いタイプの参照関係です。オブジェクトにファントム参照があるかどうかは、オブジェクトの有効期間にはまったく影響しません。また、ファントム参照を通じてオブジェクト インスタンスを取得することはできません。オブジェクトに対して仮想参照の関連付けを設定する唯一の目的は、オブジェクトがコレクターによって再利用されたときにシステム通知を受信することです。 JDK1.2以降では、仮想参照を実装するためにPhantomReferenceクラスが提供されています。

忘れられたキーワード - finalize

オブジェクトをリサイクルする必要があるかどうかを判断するときは、2 つのマーキング プロセスを経る必要があります。 1 つ目は、オブジェクトが GC ルートに接続されているかどうかを追跡することです。そうでない場合はマークされます。 2 番目は、オブジェクトが finalize メソッドを書き換えていないか、または finalize メソッドが呼び出されたか (その時点でオブジェクトは完全に死んでいる) を判断することです。

finalize メソッドがオーバーライドされて呼び出されない場合、オブジェクトは優先度の低いキュー、または実行されないキュー F-Queue に配置され、その後オブジェクトの finalize メソッドが呼び出されます。オブジェクトがメソッド内の GC ルートによって参照されている場合、オブジェクトは正常に保存されます。しかし、F-Queue が実行されない可能性があるため、この救済方法は信頼できません。一部のチュートリアルでは、リソースを解放するために finalize を推奨していますが、try-finally を使用しないのはなぜでしょうか?

このキーワードは忘れられる可能性があります。

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

マークスイープアルゴリズム

マークアンドスイープアルゴリズムは 2 つのステージで構成されます。まず、リサイクルが必要な物にマークを付けます(マークの方法は上記参照)。マーキングが完了したら、マーキングされたすべてのオブジェクトが均一にリサイクルされます。マーククリアアルゴリズムはすべてのガベージコレクションアルゴリズムの基礎であり、後続のアルゴリズムはその欠点に基づいて改良されています。

欠点:

  • 効率が低く、マーキングとクリアリングのプロセスの両方が効率的ではありません。
  • 空間は断片化されています。明確にマークされた後、連続したメモリ断片が大量に生成されます。スペースフラグメントが多すぎる場合、大きなオブジェクトがスペースを割り当てる必要があるときに、GC が事前にトリガーされます。

空のテーブルは未使用のメモリであり、緑色でマークされたオブジェクトはクリアできるオブジェクトです。これは片付ける前の状態で、きちんと整頓された家族は連続した領域を占める必要がある比較的大きなオブジェクトです。

クリア後​​の状態です。メモリ断片が多すぎます。比較的大きなファミリが割り当てられる場合、事前に新しい GC がトリガーされます。

コピーアルゴリズム

効率の問題を解決するために、メモリを 2 つの同じサイズのブロックに分割し、一度にそのうちの 1 つだけを使用するコピー アルゴリズムが開発されました。このメモリ ブロックが使い果たされると、残っているオブジェクトは他のメモリ ブロックにコピーされ、使用済みのメモリはすぐにクリアされます。このアルゴリズムは効率的ですが、スペースを無駄にしすぎます。

上図に示すように、メモリの下半分が使用されるようになりました。消去するときは、マークされていないものを上位メモリにコピーしてから、下位メモリを一括消去します。

現在、ほとんどの商用仮想マシンは、このアルゴリズムを使用して新しい世代をリサイクルしています。しかし、メモリは 1:1 ベースで割り当てられるわけではありません。IBM が特別な調査を行った結果、新世代のオブジェクトの 98% は生まれては消えていくことが判明したからです。

メモリは、より大きな Eden スペースと 2 つのより小さな Survivor スペースに分割されます。 Eden と Survivor ブロックの 1 つが使用されるたびに、リサイクル中に生き残ったオブジェクトが別の Survivor ブロックにコピーされ、使用中の Eden と Survivor はクリアされます。通常、Eden、Survivor1、Survivor2 の比率は 8:1:1 なので、メモリの 10% のみが無駄になります。

ここでの Eden を、物体が生まれる場所である Eden と、リサイクル後に生き残る物体である Survivor と訳すと、理解しやすくなります。

リサイクル後のオブジェクト数が 10% を超え、Survivor スペースが不足する場合は、割り当て保証 (Handle Promotion) のために他のメモリ (古い世代) に依存する必要があります。

マークスイープアルゴリズム

コピーコレクションアルゴリズムは、オブジェクトの生存率が高い状況には適していません。残存するオブジェクトが多すぎると、より多くのオブジェクトをコピーする必要があり、効率が低下します。また、スペースの 50% を無駄にしたくない場合は、割り当て保証のために追加のスペースを使用する必要があるため、このアルゴリズムは古い世代には適用できません。

旧世代の特性に基づいて、マークアンドスイープアルゴリズムを提案する人もいます。これは、生き残ったすべてのオブジェクトをマークした後に一方の端に移動し、境界外のメモリを直接クリアするものです。

これはリサイクル前です

これはリサイクル後です

世代別コレクションアルゴリズム

このアルゴリズムは、オブジェクトのライフサイクルに応じてメモリを複数のブロックに分割し、一般的に Java ヒープを新しい世代と古い世代に分割します。各ガベージ コレクションで多数のオブジェクトが消滅する新しい世代では、コピー アルゴリズムが使用されます。残存世代数が多く、追加のスペース保証がない古い世代では、マーク アンド スイープ アルゴリズムまたはマーク アンド クリーン アルゴリズムが使用されます。

インクリメンタルコレクター

プログラムは、所有するメモリ空間を複数のパーティションに分割します。プログラム操作に必要なストレージ オブジェクトはこれらのパーティションに分散され、一度にリサイクルされるのはパーティションの 1 つだけなので、リサイクルのためにすべてのプログラム スレッドを一時停止する必要がありません。これにより、一部のスレッドはリサイクル動作に影響を与えずに実行を継続でき、リサイクル時間が短縮され、プログラムの応答速度が向上します。

V. 結論

この記事では、ガベージ コレクションとは何か、また参照カウント、ガベージ コレクションのトレース、エスケープ分析など、Java 仮想マシンのガベージ コレクション戦略について説明します。また、マークスイープ、コピーアルゴリズム、マークコンパクトアルゴリズムなど、レストラン形式のいくつかのガベージコレクションアルゴリズムも紹介します。

原文: https://icdream.github.io/2019/01/10/jvm03/

<<:  JVMパラメータを学ぶ前に知っておくべきこと

>>:  Java仮想マシンの基本原理とプロセスを理解すれば、JVMの60%をマスターできます。

推薦する

コレクション型ウェブサイトを共有するマーケティングモデルは、コレクションの新たな人気を生み出す

実は、現在、電子商取引サイトは本当にたくさんあります。デジタル製品のYixun.com、衣料品のVa...

SEOウェブサイト最適化オペレーション市場ポジショニングの簡単な分析

ウェブサイト構築の初期段階では、どのようなサイトを作るにしても、サイトの位置づけを明確にする必要があ...

分散メッセージングシステムの設計ポイント

分散キャッシュに関しては、Redis がリードしています。しかし、メッセージ キュー MQ に関して...

SEO ゼロから学ぶ第 5 章 - ニュース ソースと Baidu のセンシティブ ワード

マーケティング手法には SEO が含まれており、SEO はマーケティングの一部です。SEO 分野で何...

最も一般的なウェブサイト収益モデルの分析

収益性は、ウェブサイトが必ず通らなければならない道のようです。多くのウェブサイトは利益を上げる目的で...

クラウド内のコンテナ用の永続ストレージの設定

コンテナの永続ストレージは、クラウドでワークロードを実行するユーザーを含むエンタープライズ ユーザー...

ブランドマーケティングで勝つための秘訣:ストーリーの伝え方を知る

旅行中にホテルに泊まらず、誰かの家を借りたいと誰かに聞かれたら、まずどの会社を思い浮かべますか?この...

SEO Taobao: 時代の流れに遅れず、最も適応力のある者だけが生き残る

Taobao のウェブサイトは、コンバージョンという形で第三者の情報を取得するためのプラットフォーム...

電子商取引の1年を振り返ると、大手電子商取引企業がプラットフォーム競争を巻き起こした。

多くのビジネス形態の中でも、電子商取引は最も多くの出来事と最も大きな変化を伴うビジネス分野となってい...

IBMはオープン性がエッジ開発の大きな利点だと語る

組織は、データが最大の価値を生み出した後、できるだけ早くそのデータを取得してそれに基づいて行動するこ...

#BlackWeek5# turnkeyinternet-ホスト 1 ドル、ホスト専用 IPv4 10 個、サーバー 9 ドル/月

10 年以上の歴史を持つアメリカの老舗企業である turnkeyinternet.net は、仮想ホ...

#BlackWeek5#: Hostus - 香港を含む 9 つのデータセンター / 10G ポート / DDOS 保護 / さまざまな特別オファー

Hostus の今年のブラックフライデーはこの記事で取り上げます。最新ニュースは次のとおりです。ワシ...

RedisやZooKeeperなどの分散ロックの原理に関する考察

まず、分散ロックの原理は、私たちが普段話しているロックと基本的に同じです。目的は、複数のスレッドが同...

デジタルプラットフォームが国境を越えた電子商取引を強化 Oracle が Secoo「クラウド」で高級ブティックライフを実現

都市部のホワイトカラー労働者の生活のペースが加速するにつれ、彼らは忙しい仕事や生活に「儀式」の感覚を...