1. 概要

このクイックチュートリアルでは、さまざまな JVMガベージコレクション(GC)実装の基本を示します。 次に、アプリケーションで特定のタイプのガベージコレクションを有効にする方法を学習します。

2. ガベージコレクションの簡単な紹介

名前からすると、ガベージコレクションは、メモリからのガベージの検索と削除を処理するようです。 ただし、実際には、ガベージコレクションは、JVMヒープスペースで使用可能なすべてのオブジェクトを追跡し、未使用のオブジェクトを削除します。

基本的に、 GC は、マークアンドスイープと呼ばれる2つの簡単なステップで機能します。

  • マーク– これは、ガベージコレクターが、使用されているメモリと使用されていないメモリを識別する場所です。
  • スイープ– このステップでは、「マーク」フェーズで識別されたオブジェクトを削除します。

利点:

  • 未使用のメモリスペースはGCによって自動的に処理されるため、手動でのメモリ割り当て/割り当て解除の処理はありません。
  • ダングリングポインタの処理のオーバーヘッドはありません
  • 自動メモリリーク管理( GC 自体は、メモリリークに対する完全なプルーフソリューションを保証することはできませんが、その大部分を処理します)

短所:

  • JVM はオブジェクト参照の作成/削除を追跡する必要があるため、このアクティビティには元のアプリケーションよりも多くのCPUパワーが必要です。 大容量のメモリを必要とするリクエストのパフォーマンスに影響を与える可能性があります。
  • プログラマーは、不要になったオブジェクトを解放するためのCPU時間のスケジューリングを制御できません。
  • 一部のGC実装を使用すると、アプリケーションが予期せず停止する可能性があります。
  • 自動化されたメモリ管理は、適切な手動のメモリ割り当て/割り当て解除ほど効率的ではありません。

3. GCの実装

JVMには、次の5種類のGC実装があります。

  • シリアルガベージコレクター
  • パラレルガベージコレクター
  • CMSガベージコレクター
  • G1ガベージコレクター
  • Zガベージコレクター

3.1. シリアルガベージコレクター

これは、基本的にシングルスレッドで機能するため、最も単純なGC実装です。 その結果、このGC実装は、の実行時にすべてのアプリケーションスレッドをフリーズします。 したがって、サーバー環境などのマルチスレッドアプリケーションで使用することはお勧めできません。

ただし、QCon2012でTwitter のエンジニアがシリアルガベージコレクターのパフォーマンスについて素晴らしい講演を行いました。これは、このコレクターをよりよく理解するための良い方法です。 。

シリアルGCは、一時停止時間の要件が少なく、クライアントスタイルのマシンで実行されるほとんどのアプリケーションに最適なガベージコレクターです。 シリアルガベージコレクターを有効にするには、次の引数を使用できます。

java -XX:+UseSerialGC -jar Application.java

3.2. パラレルガベージコレクター

これは、JVMのデフォルトのGC であり、スループットコレクターと呼ばれることもあります。 シリアルガベージコレクターとは異なり、はヒープスペースの管理に複数のスレッドを使用しますが、GCの実行中に他のアプリケーションスレッドもフリーズします。

このGCを使用すると、最大ガベージコレクションスレッドと、一時停止時間、スループット、およびフットプリント(ヒープサイズ)を指定できます。

ガベージコレクタスレッドの数は、コマンドラインオプションで制御できます -XX:ParallelGCThreads =

最大休止時間の目標(2つの間のギャップ[ミリ秒単位] GC )はコマンドラインオプションで指定されます -XX:MaxGCPauseMillis =

ガベージコレクションの実行に費やされた時間とガベージコレクションの外部で費やされた時間は、最大スループットターゲットと呼ばれ、コマンドラインオプションで指定できます。 -XX:GCTimeRatio =

最大ヒープフットプリント(プログラムの実行中に必要なヒープメモリの量)は、オプションを使用して指定されます -Xmx

Parallel Garbage Collector を有効にするには、次の引数を使用できます。

java -XX:+UseParallelGC -jar Application.java

3.3. CMSガベージコレクター

Concurrent Mark Sweep(CMS)実装は、ガベージコレクションに複数のガベージコレクタースレッドを使用します。ガベージコレクションの一時停止を短くすることを好むアプリケーション向けに設計されており、アプリケーションの実行中にプロセッサーリソースをガベージコレクターと共有できます。 。

簡単に言えば、このタイプのGCを使用するアプリケーションは、平均して応答が遅くなりますが、ガベージコレクションを実行するために応答を停止することはありません。

ここで注意すべき簡単な点は、この GC は並行であるため、並行プロセスの動作中に System.gc()を使用するなど、明示的なガベージコレクションを呼び出すと結果が生じることです。 同時モード障害/中断

合計時間がCMSガベージコレクションに費やされた時間が98% ofを超え、ヒープが回復された時間が2 % o f未満の場合、OutOfMemoryErrorがスローされます。 CMSコレクター。 必要に応じて、オプション -XX:-UseGCOverheadLimit をコマンドラインに追加することで、この機能を無効にすることができます。

このコレクターには、インクリメンタルモードと呼ばれるモードもあります。これは、Java SE 8で非推奨になり、将来のメジャーリリースで削除される可能性があります。

CMSガベージコレクターを有効にするには、次のフラグを使用できます。

java -XX:+UseParNewGC -jar Application.java

Java 9以降、CMSガベージコレクタは非推奨になりました。 したがって、JVMを使用しようとすると、JVMは警告メッセージを出力します。

>> java -XX:+UseConcMarkSweepGC --version
Java HotSpot(TM) 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated 
in version 9.0 and will likely be removed in a future release.
java version "9.0.1"

さらに、 Java14はCMSサポートを完全に廃止しました。

>> java -XX:+UseConcMarkSweepGC --version
OpenJDK 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC; 
support was removed in 14.0
openjdk 14 2020-03-17

3.4. G1ガベージコレクター

G1(ガベージファースト)ガベージコレクターは、大容量のメモリスペースを備えたマルチプロセッサマシンで実行されるアプリケーション向けに設計されています。 JDK7 Update4以降のリリースから入手できます。

G1 コレクターは、パフォーマンス効率が高いため、CMSコレクターに取って代わります。

他のコレクターとは異なり、 G1 コレクターは、ヒープを同じサイズのヒープ領域のセットに分割し、それぞれが仮想メモリの連続した範囲になります。 ガベージコレクションを実行する場合、 G1 は同時グローバルマーキングフェーズを示します(つまり、 フェーズ1は、マーキング)と呼ばれ、ヒープ全体のオブジェクトの活性を判断します。

マークフェーズが完了すると、G1はどの領域がほとんど空であるかを認識します。 最初にこれらの領域に収集され、通常はかなりの量の空き領域が生成されます(つまり、 フェーズ2、スイープとして知られています。そのため、このガベージコレクションの方法はガベージファーストと呼ばれます。

G1ガベージコレクターを有効にするには、次の引数を使用できます。

java -XX:+UseG1GC -jar Application.java

3.5. Java8の変更

Java 8u20 は、同じ文字列のインスタンスを作成しすぎてメモリの不要な使用を減らすための JVM パラメータをもう1つ導入しました。これにより、削除することでヒープメモリが最適化されますString値をグローバルシングルchar[]配列に複製します。

このパラメーターを有効にするには、 -XX:+UseStringDeduplicationJVMパラメーターとして追加します。

3.6. Zガベージコレクター

ZGC(Zガベージコレクター)は、Linuxの実験的なオプションとしてJava11でデビューしたスケーラブルな低レイテンシーのガベージコレクターです。 JDK 14は、WindowsおよびmacOSオペレーティングシステムでZGCを導入しました。 ZGC は、Java15以降の本番ステータスを取得しています。

ZGC は、アプリケーションスレッドの実行を10ミリ秒以上停止することなく、すべての高価な作業を同時に実行します。これにより、低レイテンシを必要とするアプリケーションに適しています。 色付きポインターを備えたロードバリアを使用して、スレッドの実行中に同時操作を実行し、ヒープの使用状況を追跡するために使用されます。

参照色(色付きのポインター)は、ZGCのコアコンセプトです。 これは、 ZGC が参照のいくつかのビット(メタデータビット)を使用してオブジェクトの状態をマークすることを意味します。 また、サイズが8MBから16TBの範囲のヒープを処理します。 さらに、一時停止時間は、ヒープ、ライブセット、またはルートセットのサイズによって増加することはありません。

G1と同様に、Zガベージコレクターはヒープをパーティション化しますが、ヒープ領域のサイズが異なる場合があります。

Zガベージコレクターを有効にするには、15より前のJDKバージョンで次の引数を使用できます。

java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC Application.java

バージョン15以降では、次の実験モードは必要ありません。

java -XX:+UseZGC Application.java

ZGCはデフォルトのガベージコレクターではないことに注意してください。

4. 結論

この記事では、さまざまなJVMガベージコレクションの実装とそのユースケースについて説明しました。

より詳細なドキュメントはここにあります。