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 ルーツ、麺の入ったボウル、メニューを準備します。丼が空っぽなのに注文メニューに名前がない人は緑色でマークされます。生き残ったのは、左上の麺を持っている人、その上の独身以外の人、そして家族全員です。左右の2人は麺が空っぽで注文メニューにないのですが、真ん中の人が参考にしていて、真ん中の人はたまたま丼に麺が入っている!これが「食べても帰らない人を追跡する方法」です。

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/

<<:  AIは旅行業界の困難を軽減できるか?

>>:  AIは旅行業界の困難を軽減できるか?

ブログ    

推薦する

顔認識のためのディープラーニングとオブジェクト検出のステップバイステップガイド

[[277051]]これまでの共有を通じて、顔認識の一般的なプロセスを理解しました。主に次のプロセス...

科学者らは初めてAIメタ学習を神経科学に導入し、脳画像精密医療の向上が期待される

最近、シンガポール国立大学、バイトダンス、その他の機関が共同で開発した技術的成果が、トップクラスの神...

...

IoT、AI、ビッグデータが地球を救う方法

私たちは皆、モノのインターネット (IoT)、人工知能 (AI)、ビッグデータが業界の再編とビジネス...

Python による画像前処理の完全ガイド

機械学習やコンピューター ビジョンのプロジェクトで、画像の品質が低いという問題に遭遇したことはありま...

データセンターにおける人工知能: 知っておくべき 7 つのこと

人工知能と機械学習は、日常的なタスクと高度なタスクの両方を徐々に引き継いでいます。管理者と従業員は解...

ディープマインドの創業者はAIの弟子を育て、「訓練」ではなく「教育」によってAIに宝探しを教えた

最近、DeepMind は強化学習の分野で新しいことを行いました。簡単に言えば、DeepMind の...

...

...

顔認識のゴッドファーザー、李自青氏:技術革新が業界の未来を力づける

NVIDIA の GTC CHINA 2016 テクノロジー カンファレンスでは、数多くの業界リーダ...

...

AIがKing of GloryやStarCraftをプレイしています...その背後にあるテクノロジーを理解していないのですか?ゲームAIのレビューはこちら

[[437808]]人間とコンピュータのゲームは長い歴史があり、人工知能の主要技術を検証するための主...

フォーブスの分析:深刻な問題により自動運転技術は「寒い冬」を迎える可能性がある

フォーブスによると、コーエン研究所の研究者らは最近、テスラのオートパイロットシステムへのハッキングに...

...

マイクロソフトがML.NETクロスプラットフォーム機械学習フレームワークをオープンソース化し、AIをさらに一歩前進させる

現地時間5月7日、米国シアトルでMicrosoft Buildカンファレンスが開催され、マイクロソフ...