ホームページ >Java >&#&チュートリアル >各種Javaガベージコレクタの比較まとめ
[はじめに] 2017 年ですが、ほとんどの開発者にとって、ガベージ コレクションと異性 (プログラマーが再び笑われています) という 2 つのことが依然として謎です。後者についてはあまり詳しくないので、前者について話してみようと思います。
2017 年ですが、ほとんどの開発者にとって、ガベージ コレクションと異性 (プログラマーがまた笑われています) という 2 つのことがまだ謎です。後者についてはあまり詳しくないので、特に Java 8 の登場により、この分野で多くの大きな変更と改善が行われました。その中で最も重要なのは、永続的な生成 (PermGen) の削除と、いくつかの興味深い新しい最適化 (後で説明します)。
ガベージコレクションと言えば、多くの人がその概念を理解し、日常のプログラミングに応用しています。それでも、私たちが完全には理解していないことがたくさんあり、それが痛みの原因です。 JVM に関する最大の誤解は、JVM にはガベージ コレクターが 1 つしかないということですが、実際には 4 つの異なるコレクターがあり、それぞれに長所と短所があります。コレクターが異なると、スループットとアプリケーションの一時停止時間に大きな違いが生じる可能性があるため、JVM は自動的にどちらかを選択することはありません。それはあなたと私次第です。
これら 4 つのリサイクル アルゴリズムの共通点は、すべて世代別であるということです。つまり、マネージド ヒープをいくつかの領域に分割しており、ヒープ内の多くの オブジェクト の ライフサイクル が迅速にリサイクルできることを前提としています。このトピックについてはこれまで多くの紹介がなされてきたため、ここではこれらのさまざまなアルゴリズムとその長所と短所について直接話すつもりです。
シリアル リサイクラーは、主にシングルスレッド環境 (32 ビットまたは Windows など) および比較的小規模な環境向けであるため、使用することは考えられません。このコレクターは、動作中にすべてのアプリケーション スレッドをフリーズするため、サーバー側アプリケーションでの使用が完全に不可能になります。
使用方法: -XX:+UseSerialGC JVM パラメーターをオンにして使用できます。
次は、並列コレクター (Parallel コレクター) です。これは JVM のデフォルトのコレクターです。その名前が示すように、その最大の利点は、複数のスレッドを使用してヒープをスキャンして圧縮できることです。欠点は、マイナー GC かフル GC かに関係なく、アプリケーション スレッドが一時停止されることです。並列コレクターは、一時停止を許容し、コレクターによって発生する CPU オーバーヘッドを削減しようとするアプリケーションに最適です。
並列コレクターの次は、CMS コレクター (同時マークスイープ) です。このアルゴリズムは、複数のスレッド (同時実行) を使用してヒープをスキャンし、使用されなくなってリサイクル (スイープ) できるオブジェクトにマークを付けます。このアルゴリズムは 2 つの状況で「ストップ ザ ワールド」モードに入ります。ルート オブジェクト (スレッド エントリ ポイントまたは静的変数によって到達可能な古い世代のオブジェクト) の初期マーキングを行うときと、このときです。アルゴリズムが同時に実行されている場合、アプリケーションはヒープの状態を変更するため、戻ってマークしたオブジェクトが正しいことを再度確認する必要があります。
このコレクターを使用する際の最大の問題は、新世代と旧世代をリサイクルするときに競合条件が発生する状況を指すプロモーションの失敗に遭遇することです。コレクターが若いオブジェクトを古い世代に昇格する必要があり、現時点で古い世代に余分なスペースがない場合、コレクターは最初に STW (Stop The World) フル GC を実行することしかできません。これは正しい状況です。 CMS が避けたいこと。これが起こらないようにするには、古い世代のサイズを増やす (またはヒープ全体のサイズを増やす) か、オブジェクト割り当ての速度と競合できるようにバックグラウンド スレッドをコレクターに割り当てる必要があります。 。このアルゴリズムのもう 1 つの欠点は、並列コレクターと比較して、複数のスレッドを使用してスキャンとリサイクルを実行するため、アプリケーションがより高いレベルのスループットを提供し続けることができることです。ほとんどの長時間実行プログラムにとって、アプリケーションの停止は非常に有害です。現時点では、CMS リサイクラーの使用を検討できます。ただし、このアルゴリズムはデフォルトでは有効になっていません。有効にするには XX:+UseConcMarkSweatGC を指定する必要があります。ヒープが 4G 未満で、アプリケーションの中断を避けるためにより多くの CPU リソースを割り当てたい場合、これが選択すべきコレクターです。ただし、ヒープが 4G より大きい場合は、最後のヒープである G1 コレクターを使用することをお勧めします。
G1 (ガベージ ファースト) コレクターは、JDK 7update 4 で初めて導入されました。その設計目標は、4GB を超えるヒープをより適切にサポートすることです。 G1 コレクターはヒープを 1MB から 32MB までのサイズの領域に分割し、複数のバックグラウンド スレッドを使用してそれらをスキャンします。 G1 コレクターは、最も多くのガベージを含む領域を最初にスキャンします。これがその名前の由来です (ガベージ ファースト)。このコレクターは、-XX:UseG1GC フラグを使用して有効にできます。
この戦略により、バックグラウンド スレッドが不要なオブジェクトのスキャンを完了する前にヒープが使い果たされる可能性が低くなり、その場合、コレクターはアプリケーションを一時停止する必要があり、これにより STW のリサイクルが発生します。 G1 のもう 1 つの利点は、CMS コレクターがフル GC 中にのみこれを行うのに対し、G1 は常にヒープを圧縮することです。
過去数年間、Dadu は物議を醸す分野であり、多くの開発者が単一マシンの単一 JVM モデル から単一マシンのマルチ JVM マイクロサービスとコンポーネント化された アーキテクチャ に移行してきました。これは、アプリケーション コンポーネントの分離、デプロイメントの簡素化、アプリケーション クラスをメモリに再ロードするオーバーヘッドの回避など、さまざまな要因によって推進されます (これは Java 8 で改善されました)。 ただし、これを行う主な目的は、大規模な GC での長い「世界停止」一時停止 (大規模なコレクションでは完了までに数秒かかります) を回避することです。
Dockerなどのコンテナ テクノロジーもこのプロセスを加速し、複数のアプリケーションを同じ物理マシンに簡単にデプロイできるようにします。 Java 8 および G1 コレクター
重複排除です。文字列 (内部 char[]配列を含む) がヒープ領域の大部分を占めるため、この新しい最適化は、G1 コレクターがヒープ内で繰り返し発生する文字列を識別し、それらが同じ文字列を指すように設計されています。 ] 配列を使用して、ヒープの使用効率が非効率になる同じ文字列の複数のコピーを回避します。 -XX:+UseStringDeduplication JVM パラメーターを使用して、この機能を試すことができます。 Java 8 と永続生成 Java 8 での最大の変更は、もともとクラスのメタデータ、常駐文字列、および静的変数にスペースを割り当てるために使用されていた永続生成が削除されたことです。これまでは、開発者は、多数のクラスをロードするアプリケーションのヒープ率を特に最適化し、調整する必要がありました。これは長年にわたって当てはまり、多くの OutOfMemory 例外の原因となっているため、JVM が引き継ぐのは素晴らしいことです。それでも、それ自体では、開発者がアプリケーションを異なる JVM に分離する可能性が減りません。
に応じて、スループットが増減する可能性があります。
以上が各種Javaガベージコレクタの比較まとめの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。