ガベージコレクションについて話しましょう。

ガベージコレクションについて話しましょう。

[[354376]]

この記事はWeChatの公開アカウント「Java Geek Technology」から転載したもので、著者はYaxue Fansです。この記事を転載する場合は、Java Geek Technology の公開アカウントにお問い合わせください。

JVM の自動メモリ管理により、開発者が行うべき作業がガベージ コレクターによって行われるようになります。

他人が行うため、希望通りにならない可能性もあるため、ガベージコレクションに関する内容を理解する必要があります。

参照カウントと到達可能性分析

ガベージ コレクション、ガベージ コレクション、つまり、一部のメモリが一部のオブジェクトに割り当てられていますが、これらのオブジェクトは使い果たされているため、占有されているメモリを解放する必要がありますが、まだ解放されていません。

そこで、疑問が生じます。オブジェクトが使い果たされたことをどのように判断するのでしょうか?

その方法の 1 つは参照カウントです。

参照カウント方式は、各オブジェクトに参照カウンタを追加して、そのオブジェクトを指す参照の数をカウントする方法です。

たとえば、特定のオブジェクトに割り当てられた参照がある場合、このオブジェクトの参照カウンターは +1 になります。このオブジェクトを指す参照が別の値に割り当てられている場合、このオブジェクトの参照カウンターは -1 になります。このように、このオブジェクトの参照カウンタが 0 の場合、このオブジェクトは使い果たされており、占有しているメモリ領域をリサイクルできると想定できます。

この解決策は完璧に思えますが、致命的な欠陥があります。それは、循環参照を処理できないことです。

たとえば、A と B は相互に参照しており、A または B への他の参照はありません。この場合、A と B によって占有されているメモリは解放できますが、相互に参照があるため、この時点では参照カウンターは 0 ではありません。この場合はリサイクルできません。

現在、オブジェクトは 2 つだけです。さらに 2 つ、さらに 2 つあると、循環参照を持つオブジェクトが多くなりすぎて、メモリ リークが発生します。

参照カウント方式の欠点を踏まえて、現在主流のJVMガベージコレクターは到達可能性解析アルゴリズムを採用している。

このアルゴリズムの本質は、一連の GC ルートを初期のライブ オブジェクト セットとして使用し、このセットから開始して、セットによって参照できるすべてのオブジェクトを探索し、これらのオブジェクトをセットに追加することです。このプロセスはマーキングと呼ばれます。トラバーサルの最後に、探索されていないオブジェクトはリサイクル可能なオブジェクトです。

では、GC ルートとは何でしょうか?一般的に、次のような内容が含まれます (ただし、これらに限定されません)。

  • Java メソッド スタック フレーム内のローカル変数
  • ロードされたクラスの静的変数
  • JNIハンドル
  • 開始されて停止されていないJavaスレッド

先ほど、参照カウント方式には循環参照の問題があるとして、現在主流のガベージ コレクターはすべて到達可能性解析方式を採用していると述べました。つまり、循環参照の問題を解決します。実はこれも比較的理解しやすいのです。 A と B は相互に参照していますが、この時点では GC ルートから A と B に到達する方法がないため、それらは存続オブジェクトのコレクションには入れられず、自然にリサイクルされます。

しかし、実際にはまだ問題が残っています。たとえば、マルチスレッド環境では、アクセスされたオブジェクトの参照を他のスレッドが更新しますが、マルチスレッドは並列に実行されます。この時点で、到達可能性分析メソッドは参照を null に設定しているか、オブジェクトはまだ使用中ですが、到達可能性分析メソッドはそれをアクセスされていないオブジェクトとしてマークし、リサイクルされています。この状況により、JVM が直接クラッシュする可能性があります。

ストップ・ザ・ワールドとセーフポイント

到達可能性解析方法にも欠点はあるので、解決策はあるはずですよね?より暴力的な方法は「ストップ・ザ・ワールド」です。名前の通り、全世界を止めることを意味します。つまり、ガベージ コレクションが進行中の場合、ガベージ コレクション以外のスレッドはすべて動作を停止し、まずガベージ コレクターの作業を完了させる必要があります。これはいわゆる GC 一時停止です。

Stop-the-World はセーフポイント メカニズムを通じて実現されます。それはどういう意味ですか?シナリオを想像してみましょう。今、あなたはとても楽しくコードを入力し、アイデアも浮かび、良い状態にあり、楽しく仕事をしています。突然、理由もなく、今はコードを入力しないよう求められます。不幸になりますか?アイデアを得るのは簡単ではありませんよね?理由を述べずに停止するよう求められます。それは無理じゃないですか?

同じシナリオでは、スレッドは現在非常に正常に実行されており、1 秒以内にタスクを完了します。このとき、JVM は Stop-the-world 要求を受信し、何も言わずにすべてのスレッドを停止します。それは良くないですか?次に、セーフポイント メカニズムが機能します。セーフ ポイント メカニズムを使用すると、JVM は Stop-the-world 要求を受信すると、Stop-the-world を要求しているスレッドが排他的に作業を実行できるようにする前に、すべてのスレッドがセーフ ポイントに到達するまで待機します。

では、安全ポイントはいつでしょうか?たとえば、Java プログラムが JNI を介してネイティブ コードを実行する場合、このコードが Java オブジェクトにアクセスせず、Java メソッドを呼び出さず、元の Java メソッドに戻らない場合、Java 仮想マシンのスタックは変更されず、このネイティブ コードは安全ポイントとして使用できます。この安全ポイントを離れない限り、ガベージ コレクションの実行中でも JVM はこのネイティブ コードを実行し続けることができます。

ネイティブ コードは JNI API を介して上記の 3 つの操作を完了する必要があるため、JVM は API の入り口でセーフポイント ポーリングを実行して、セーフポイントに留まるように要求している他のスレッドがあるかどうかを確認し、必要に応じて現在のスレッドを一時停止するだけで済みます。

ガベージコレクションの3つの方法

生き残ったオブジェクトをマークした後、ガベージ コレクションを実行できます。

主流のガベージコレクション方法は、スイープ、コンパクト、コピーの 3 種類に分けられます。

クリアとは、死んだオブジェクトによって占有されていたメモリを空きメモリとしてマークし、空きリストに記録することです。新しいオブジェクトが必要な場合、空きメモリがフリーリスト内で直接検索され、新しいオブジェクトに割り当てられます。

ただし、ここで問題が発生するのは、デッド オブジェクトによって占有されるメモリがランダムである可能性があるからです。コレクションが完了すると、メモリは断片化されます。このとき、オブジェクトが連続したメモリ空間を要求すると、断片化されたメモリ空間が十分であっても割り当てることができません。

圧縮とは、生き残ったオブジェクトをメモリ領域の開始位置に集めて、連続したメモリ空間を残すことです。そうすることでメモリの断片化の問題を解決できますが、圧縮アルゴリズムのパフォーマンスのオーバーヘッドが犠牲になります。

コピーとは、メモリ領域を 2 つの等しい部分に分割し、それぞれ from と to の 2 つのポインターで管理し、from ポインターが指すメモリ領域のみを使用してメモリを割り当てることを意味します。ガベージ コレクションが実行されると、生き残ったオブジェクトは to ポインタが指すメモリ領域にコピーされ、from ポインタと to ポインタの内容が交換されます。

レプリケーション方式はメモリの断片化の問題も解決できますが、その欠点も明らかです。メモリ領域が 2 つの均等な部分に分割されているため、使用率は比較的低くなります。最大値は 50% であり、それ以上にすることはできません。

JVM でのガベージコレクションの適用

上記の 3 つのガベージ コレクション方法は理論的なものですが、JVM ではどのように適用されるのでしょうか。

まず、JVM ヒープの分割を理解する必要があります。これはおおよそ次のようになります。

JVM はヒープ領域を新しい世代と古い世代に分割します。新世代はさらに、エデン エリアと、同じサイズの 2 つのサバイバー エリアに分割されます。

プログラムが新しい命令を呼び出すと、Eden 領域にストレージ オブジェクトとしてメモリが割り当てられます。ただし、ヒープ領域はスレッドによって共有されるため、ここで領域を割り当てるときには同期が必要です。そうしないと、2 つのオブジェクトがメモリの一部を共有する場合、それらのオブジェクトが競合することになります。

2 つのオブジェクト間の競合を回避するために、JVM は各スレッドに、スレッド専用の TLAB (スレッド ローカル割り当てバッファ、仮想マシン パラメータ -XX:+UseTLAB に対応、デフォルトで有効) として JVM から連続メモリを申請するように要求します。

エデンエリアは常に割り当てられます。スペースが完全に割り当てられた場合はどうすればよいでしょうか?このとき、JVM はマイナー GC をトリガーして新しい世代のガベージを収集し、生き残ったオブジェクトは Survivor 領域に送信されます。

図からわかるように、Survivor 領域は 2 つあり、1 つは from で、もう 1 つは to です。 to が指す Survivor 領域は空です。

マイナー GC が発生すると、from が指す Eden 領域と Survivor 領域内の生き残ったオブジェクトが to が指す Survivor 領域にコピーされ、from ポインタと to ポインタが交換されます。これにより、次のマイナー GC 時に、to が指す Survivor 領域がまだ空であることが保証されます。

同時に、JVM は Survivor 領域内のオブジェクトが何回コピーされたかを記録します。オブジェクトが 15 回コピーされると (仮想マシン パラメータ -XX:+MaxTenuringThreshold に相当)、オブジェクトは古い世代に昇格されます。

では、マイナー GC が発生した場合、どのガベージ コレクション方法がより適切でしょうか?コピー方式、つまりマークコピーアルゴリズムの方が適しています。なぜ?新しい世代では、ほとんどの Java オブジェクトは短期間しか存続しないため、より短時間でガベージ コレクション アルゴリズムを使用して、ほとんどのガベージを新しい世代でリサイクルできるようになります。マークコピーアルゴリズムを使用する場合、理想的には、Eden 領域内のすべてのオブジェクトが死んでいるので、コピーするデータは非常に少なく、このときにこのアルゴリズムの利点が大きく反映されます。

<<:  5つの分散トランザクションソリューションを比較すると、私は依然としてAlibabaのSeata(原則+実践)を好む

>>:  JD.comの「クラウドチェーン計画」が正式に開始され、パートナーと協力して産業サプライチェーンの新しいパターンを形成する

推薦する

クラウド コンピューティングと DevOps: 継続的インテグレーション/継続的デリバリーと市場分析

今日、企業は競合他社よりも速く、高品質のソフトウェアを提供するという大きなプレッシャーにさらされてい...

どのような Web ページのリダイレクトが不正行為とみなされないのでしょうか?

絶対的に正しいとか、絶対的に間違っているとかいうものは存在せず、この言葉は決して時代遅れになることは...

美的HVACビル:デジタルとインテリジェントの総合ソリューションプロバイダーになる

[51CTO.comからのオリジナル記事] 第15回中国IDC業界年次式典2020が開催されている中...

2018 年にクラウド コンピューティングを使用すべき 5 つの理由

シンプルなペンと紙だけでビジネスを正しい方向に進めることができる時代は終わりました。最近は何でもイン...

ワンストップサービスを備えたソフトウェアとアプリケーションのショッピングモールを構築する方法

2011 年には、主要なモバイル アプリケーション ストアが急速に登場し、いくつかのグループに分かれ...

SEO、SEM、WeChatパブリックアカウント運用を通じて正確なユーザーを獲得し、最大限のコンバージョンを達成する方法

SEOテクノロジーを使用して、予算ゼロで Web サイトの正確なトラフィックを 2 倍にするにはどう...

Baidu Share はウェブサイトにトラフィックをもたらし、ランキングを向上させることができますか?

最近、Baidu で検索すると、図に示すように、一部の Web サイトに余分な「小さな手」と数字が表...

クラウドネイティブインフラストラクチャについて - EventMesh イベントドリブンメッシュ

今日はイベント駆動型メッシュであるEventMeshについてお話します。実際、クラウド ネイティブ ...

タオバオの顧客がキーワードの最適化価値を素早く判断できるようにするための4つのステップ

タオバオアフィリエイトに最適化する価値のあるキーワードは、ウェブサイトのコンバージョン率をすぐに高め...

業界リーダーが懸念するクラウドコンピューティングの問題

[[239187]]クラウド コンピューティングの現状と将来についての洞察を得るため、InfoWor...

企業ウェブサイトを構築・運営するための7つのステップ

諺にあるように、軍隊が出発する前に、まず食糧と飼料を送らなければなりません。ウェブサイトを成功させた...

ウェブ編集者のリスニング、スピーキング、リーディング、ライティングのスキルを向上させる方法

オンラインメディアのほとんどの管理者は、この問題に悩まされています。編集者のリスニング、スピーキング...

2021年から2022年にかけて、14人のCEOから見た中国のSaaS市場

SaaS が 2021 年に入ると、風が再び強まります。資本市場の熱狂はそれ自体が物語っているが、そ...