Javaの動作原理を知ろう2 -ガベージコレクション編-

Javaの動作原理を知ろう2 -ガベージコレクション編-

前回は「Javaヒープの動作」をご紹介しましたが、今回は続編としてJavaヒープのクリーンナップを自動的に行ってくれるガベージコレクションの動作について紹介したいと思います。各クラウドソリューションを使用したシステムの運用管理においては、ヒープ管理によるリソースの管理に加えて、ガベージコレクションの管理も必要です。適切な設定を施さないと、不必要にスケールアウト/スケールアップを行うことになりかねません…。

ガベージコレクションって?

まずは今回のスコープを決定することから始めましょう。 ガベージコレクション(GC)とは、Javaヒープ上に存在する未使用のオブジェクトを解放してくれる機能 です。この存在のおかげで開発者はリソースの管理から解放され、本来実装すべき機能要求の実装に注力できるという恩恵を得ることができます。

ただ、ガベージコレクションの存在は、JVM仕様において定義されているものの、そのアルゴリズムや実装方法は多種多様であり、数多のJVMベンダ間で、また同じベンダ内においてもバージョンによって動作やオプションに相違があります。
今回は HotSpot VM におけるガベージコレクションの種類 をご紹介してみたいと思います。

ガベージコレクションの種類

多くのJVM実装におけるヒープの管理については、多くのベンダが 世代別管理 を行っており、Young世代においては動作コストの小さいマイナーGCを、Old世代においては動作コストの大きいメジャーGCを動かすことで、ヒープ内の不要なオブジェクトを回収しています。
世代別管理については、詳しくは前回のコラムをご覧ください。
Javaの動作原理を知ろう① -ヒープ編-
各GCはJavaスレッドとして動作しますが、それぞれの 動作アルゴリズム を 実行時のオプション指定で変更することが可能 です。

今回検証した環境(CentOS 7.3、JDK1.8.0_111)において有効な主要なアルゴリズム は以下のとおりです。

  • シリアルコレクタ (-XX:+UseSerialGC)
  • パラレルコレクタ (-XX:+UseParallelGC)
  • コンカレントコレクタ (-XX:+UseConcMarkSweepGC)
  • ガベージファースト・ガベージコレクタ:G1GC (-XX:+UseG1GC)

上記のアルゴリズムは今回取り上げているHotSpot VMにおいて有効なもののため、お使いのJVM環境において有効なアルゴリズムは別途ご確認ください。

また、システムにおけるガベージコレクションの動作チューニングの手間を抑えるため、ガベージコレクタエルゴノミクス と呼ばれる機能によって マシンスペック に応じた自動調整 が通常は行われます。
2GB以上の物理メモリおよび2コア以上の条件がそろえば、サーバクラスマシン と認識され、それ以外の場合には クライアントクラスマシン と認識され、実行エンジン、ヒープサイズやガベージコレクタのアルゴリズム等、必要最低限ではありますが調整が行われます。

詳細のオプションについては HotSpot VMのリファレンス をご覧ください。

シリアルコレクタ

昨今のハードウェアの廉価化も進み、コンシューマPCにおいてもCPUコアが複数搭載されているケースも普通になってきましたが、シリアルコレクタは従来のシングルコアマシン用に設計されている最も基本的なガベージコレクタになります。特にこれといった性能上の利点はありませんが、クライアントスペックマシンにおけるデフォルトのガベージコレクタ になります。マイナーGCおよびメジャーGCともにアプリケーションスレッドの実行を中断し、シングルスレッドで動作します。

他のガベージコレクタや、JVM内部のバグ等による ワークアラウンドとして使用 することが想定されます。

シリアルコレクタの動作イメージ

パラレルコレクタ

シリアルコレクタでは、マイナーGCおよびメジャーGCの発生時には、アプリケーションスレッドは動作せず、が停止することになります。

それに対し、パラレルコレクタ はマイナーGCおよびメジャーGCの実行に際して、その名の通りパラレル(並列に)実行します。アプリケーションスレッドの実行は中断されますが、ガベージコレクション自体のスループットは向上します。パラレルコレクタ はマルチコアを搭載する サーバクラスマシンにおけるデフォルトのガベージコレクタ です。
アプリケーションの応答要件に際してある程度の許容が認められる バッチ系のシステムについて適用 されることが想定されます。

パラレルコレクタの動作イメージ

コンカレントコレクタ

パラレル(並列)と コンカレント(並行) 、その区別は何でしょうか。
並列は一つのタスクを複数に分割して一緒に動かすことを意味しますが、並行はそれぞれ異なるタスクを一緒に動かすことを意味します。
コンカレントコレクタ は前述した二点のコレクタの動作を、アプリケーションスレッドの実行と並行して行います。そのためアプリケーションの応答要件が重視される オンライン系のシステムについて適用 されることが想定されます。ただオブジェクト回収のプロセスにおいて何度かスレッド間の同期処理が発生するため、アプリケーションの応答性は確保されるものの、アプリケーション全体のスループットは低下する可能性があります。

以下のプロセスにおいて、アプリケーションが一時停止に陥るのは 1 と 3 になります。

  1. イニシャルマーク :ルート参照のマーキング
  2. コンカレントマーク :参照可能なオブジェクトへのマーキング、
  3. リマーク :コンカレントマークによってマーキングできなかったオブジェクトへのマーキング
  4. コンカレントスイープ :オブジェクトを解放する
  5. リセット :次回のコレクションのためのデータ構造をリセットする

また、ヒープの使用率がFullになったタイミングで GC が発生する他のコレクタと比較し、起動するトリガとなる ヒープ使用率の閾値の設定が可能 ですが、設定値によっては GC プロセス終了後まもなく GC プロセスが発生する可能性があり、アプリケーション全体のスループットをさらに低下させる可能性があります。

コンカレントコレクタの動作イメージ

G1GC(Garbage First Garbage Collector)

G1GC (Garbage First Garbage Collector) は JDK6より導入された比較的新しいコレクタ で、実行環境としては大容量メモリを搭載するマルチプロセッサマシンを対象としています。 コンカレントコレクタの後継 として設計されており、マイナーGCやメジャーGCに相当する回収はアプリケーションスレッドと並列に行われます。

通常のGCプロセスは、一度開始されると、最大限にヒープを回収するまで他のアプリケーションスレッドの実行を抑制しますが、G1GCでは アプリケーションの停止時間の目標値を設定 することができます。また、ヒープを リージョン と呼ばれる小さな領域に均等に細分化することで、未使用オブジェクトの発見と回収、および別リージョンへの退避を、複数のプロセッサで効率的に実行されることが期待されます。
各リージョンは、ヒープ内のオブジェクトの生存状況やオブジェクトのサイズ等の情報に基づいて、流動的に再編成されます。

G1GCにおけるリージョンのサイズは1MB~32MBの間で調整が可能です。リージョンに入りきらないオブジェクトについては、Humongous リージョン と呼ばれる複数の基本リージョンにまたがる領域に格納され、余剰分は別リージョンとしては扱われません.。そのため、取り扱う大きなオブジェクトのサイズが 指定リージョンサイズの倍数をわずかに上回る際には、リージョンの断片化が懸念 されますので、Humongousリージョンではなく、基本リージョンに入りきるように リージョンサイズを調整 します。

G1GCのリージョン

適用されているガベージコレクタを確認するには

GC の回数や使用アルゴリズム、その効果に関しては、GUI/CUI ともに様々なツールが JDK に標準で用意 されています。GUI が使用できる環境であれば、JConsole(JDK5~)、VisualVM(JDK6~)、JavaMissionControl(JDK7~) 等、様々なものがあります。実行する環境に制限がある場合もありますのでご注意ください。

下記画像は、スタンダードな JConsole による G1GC での実行概要 になります。JDK8 からはグラフィカルな表示上のG1GCへの対応はまだ不十分ですが、Metaspace の表示やマイナーGC/メジャーGC の確認は可能 になっています。

JConsoleを使用したガベージコレクタの確認

まとめ

HotSpot VMにおけるガベージコレクションの種類とその特性を紹介してきましたが、実際のところ併用するオプションも様々あり、またアプリケーションやハードウェアの特性に応じて調整行う必要があります。ガベージコレクションの動作コストは場合によってはアプリケーションの性能要件に大きく影響しますので、ヒープの調整も含め試験環境において十分な検討を行うことが重要です。

ページの都合上、詳細な設定方法や特定環境における検証までは至りませんでしたが、ガベージコレクションのチューニングを行うための勘所としていただければ幸いです。

記事は、予告なく変更または削除される場合があります。
記載された情報は、執筆・公開された時点のものであり、予告なく変更されている場合があります。
また、社名、製品名、サービス名などは、各社の商標または登録商標の場合があります。