JVMガベージコレクター
1. 概要
このクイックチュートリアルでは、さまざまなJVM Garbage Collection (GC)の実装の基本を示します。 さらに、アプリケーションで特定の種類のガベージコレクションを有効にする方法についても説明します。
2. ガベージコレクションの簡単な紹介
名前から、Garbage Collectionはメモリからガベージを見つけて削除することを扱っているように見えます。 ただし、実際には、Garbage Collectionは、JVMヒープスペースで使用可能なすべてのオブジェクトを追跡し、未使用のオブジェクトを削除します。
簡単に言うと、GCは、マークアンドスイープと呼ばれる2つの簡単なステップで機能します。
-
Mark –は、ガベージコレクタが使用中のメモリと使用されていないメモリを識別する場所です。
-
Sweep –このステップでは、「マーク」フェーズで識別されたオブジェクトを削除します
利点:
-
未使用のメモリスペースはGCによって自動的に処理されるため、手動のメモリ割り当て/割り当て解除処理はありません
-
Dangling Pointerを処理するオーバーヘッドはありません
-
自動Memory Leak管理(GC自体は、メモリリークに対する完全な証拠ソリューションを保証することはできませんが、その大部分を処理します)
デメリット:
-
JVMはオブジェクト参照の作成/削除を追跡する必要があるため、このアクティビティには元のアプリケーションに加えてより多くのCPUパワーが必要です。 大きなメモリを必要とするリクエストのパフォーマンスに影響を与える可能性があります
-
プログラマは、不要になったオブジェクトを解放するためのCPU時間のスケジューリングを制御できません。
-
一部のGC実装を使用すると、アプリケーションが予期せず停止する可能性があります
-
自動メモリ管理は、適切な手動メモリ割り当て/割り当て解除ほど効率的ではありません
3. GCの実装
JVMには、次の4種類のGC実装があります。
-
シリアルガベージコレクター
-
並列ガベージコレクター
-
CMSガベージコレクター
-
G1ガベージコレクター
3.1. シリアルガベージコレクター
基本的に単一のスレッドで動作するため、これは最も単純なGC実装です。 その結果、this GC implementation freezes all application threads when it runs。 したがって、サーバー環境などのマルチスレッドアプリケーションで使用することはお勧めできません。
ただし、QCon 2012にはSerial Garbage Collectorのパフォーマンスに関するTwitterエンジニアによるan excellent talkがありました。これは、このコレクターをよりよく理解するための良い方法です。
シリアルGCは、一時停止時間が短く、クライアントスタイルのマシンで実行されるほとんどのアプリケーションに最適なガベージコレクターです。 Serial Garbage Collectorを有効にするには、次の引数を使用できます。
java -XX:+UseSerialGC -jar Application.java
3.2. 並列ガベージコレクター
これはJVMのデフォルトのGCであり、スループットコレクタと呼ばれることもあります。 Serial Garbage Collectorとは異なり、このuses multiple threads for managing heap space。 ただし、GCの実行中に、他のアプリケーションスレッドもフリーズします。
このGCを使用すると、最大ガベージコレクションthreads and pause time, throughput and footprint(ヒープサイズ)を指定できます。
ガベージコレクタスレッドの数は、コマンドラインオプション-XX:ParallelGCThreads=<N>で制御できます。
最大一時停止時間の目標(2つのGC間のギャップ[ミリ秒])は、コマンドラインオプション-XX:MaxGCPauseMillis=<N>で指定されます。
最大スループット目標(ガベージコレクションの実行に費やされた時間とガベージコレクションの外部で費やされた時間に関して測定)は、コマンドラインオプション-XX:GCTimeRatio=<N>.で指定されます。
最大ヒープフットプリント(実行中にプログラムが必要とするヒープメモリの量)は、オプション-Xmx<N>.を使用して指定されます。
Parallel Garbage Collectorを有効にするには、次の引数を使用できます。
java -XX:+UseParallelGC -jar Application.java
3.3. CMSガベージコレクター
Concurrent Mark Sweep (CMS)実装は、ガベージコレクションに複数のガベージコレクタスレッドを使用します。 これは、ガベージコレクションの一時停止を短くすることを好み、アプリケーションの実行中にプロセッサリソースをガベージコレクタと共有する余裕があるアプリケーション向けに設計されています。
簡単に言えば、このタイプのGCを使用するアプリケーションは、平均して応答が遅くなりますが、ガベージコレクションの実行に対する応答を停止しません。
ここで注意すべき簡単な点は、このGCは並行であるため、並行プロセスの動作中にSystem.gc()を使用するなど、明示的なガベージコレクションを呼び出すと、Concurrent Mode Failure / Interruptionが発生することです。
合計時間の98%以上がCMSガベージコレクションに費やされ、ヒープの2%未満が回復された場合、OutOfMemoryErrorはCMScollectorによってスローされます。 s。 必要に応じて、コマンドラインにオプション-XX:-UseGCOverheadLimitを追加することにより、この機能を無効にすることができます。
このコレクターには、Java SE 8で非推奨になり、将来のメジャーリリースで削除される可能性がある増分モードとして知られるモードもあります。
CMS Garbage Collectorを有効にするには、次のフラグを使用できます。
java -XX:+UseParNewGC -jar Application.java
3.4. G1ガベージコレクター
G1 (Garbage First) Garbage Collectorは、大容量のメモリスペースを持つマルチプロセッサマシンで実行されるアプリケーション向けに設計されています。 JDK7 Update 4以降のリリースで利用可能です。
G1コレクターは、パフォーマンス効率が高いため、CMSコレクターに置き換わります。
他のコレクターとは異なり、G1コレクターは、ヒープを同じサイズのヒープ領域のセットに分割します。各領域は、仮想メモリの連続した範囲です。 ガベージコレクションを実行する場合、G1は同時グローバルマーキングフェーズを示します(つまり、 ヒープ全体のオブジェクトの活性を決定するためのMarking)として知られるフェーズ1。
マークフェーズが完了すると、G1はどの領域がほとんど空であるかを認識します。 これらの領域で最初に収集され、通常かなりの量の空き領域が生成されます(つまり、 Sweeping).として知られるフェーズ2このため、このガベージコレクションの方法はガベージファーストと呼ばれます。
G1 Garbage Collectorを有効にするには、次の引数を使用できます。
java -XX:+UseG1GC -jar Application.java
3.5. Java8の変更
Java 8u20は、同じString.のインスタンスを作成しすぎて、メモリの不要な使用を減らすために、もう1つのJVMパラメータを導入しました。これにより、重複するString値がグローバルシングルchar[]配列。
このパラメータは、JVMパラメータとして-XX:+UseStringDeduplicationを追加することで有効にできます。
4. 結論
このクイックチュートリアルでは、さまざまなJVM Garbage Collectionの実装とそのユースケースを確認しました。
より詳細なドキュメントはhereにあります。