Javaはどのように動くのか~図解でわかるJVMの仕組み

第9回[最終回]HotSpot JVMのGCを選択しよう

HotSpot JVMを使うとき、どのようにGCを設定していますか?

検索して出てきたホームページを見て

「とりあえずこのホームページにあるように最新のGCを指定したし、同じようにオプションを設定したから大丈夫だろ」

と思ってしまう話をよく見聞きします。

図1 誤ったGCの選択
図1 誤ったGCの選択

しかし、たとえばバッチのようにスループットを意識すべき処理にもかかわらず、レスポンスタイム重視のGCを選んでしまうのは適切ではありません。

最終回となる今回は、HotSpotにはどのようなGCがあり、どのようにそれらを選択すれば良いのかを紹介します。

4つのGCを使いこなす

HotSpot JVMには、以下の4つのGCが実装されています。

  • シリアルGC
  • パラレルGC
  • コンカレント マーク&スイープGC(CMS)
  • ガベージファーストGC(G1GC)

1つずつ見ていきましょう。

シリアルGC

このGCの特徴は、ヒープの空き領域が少なくなるとシングルスレッドでマーク&スイープとコンパクションを行うことです。

昔はデフォルトでしたが、マルチコア化が進み、かつヒープサイズが大きくなった今では、GCに時間がかかり、停止時間が長くなってしまうため、積極的に使うことは少ないでしょう(現在も、シングルコア環境ではデフォルトです⁠⁠。

図2 シリアルGC
図2 シリアルGC

パラレルGC

マルチコア環境ではこのGCがデフォルトです。

このGCの特徴は、ヒープの空き容量が少なくなると、マルチスレッドでマーク&スイープとコンパクションを行うことです。複数のスレッドでGCすることで、アプリケーションの停止時間がシリアルGCに比べて短くなり、アプリケーションを実行できる時間が長くなります。そのため、スループットが高くなるでしょう。

図3 パラレルGC
図3 パラレルGC

コンカレント マーク&スイープGC(CMS)

CMSの特徴は、アプリケーションと同時に実行できるフェーズと、アプリケーションを止めて実行するフェーズに分かれていることです。

これらのフェーズのうち、図4の実線部である①initialフェーズと③remarkフェーズのみがアプリケーションを停止させます。

②コンカレントマーク&プリクリーン、④コンカレントスイープ、⑤リセットはコンカレントに実行されるため、アプリケーションと同時に実行されます。

図4 CMS
図4 CMS

CMSでは、GCで使用するスレッド同士の協調処理などにCPUリソースを使わなければならないため、アプリケーションのスループット低下が見込まれます。しかし、一部のフェーズではアプリケーションを停止する必要がないため、アプリケーション全体の停止時間は短くなります。その結果、GCがレスポンスタイムに与える影響が小さくなるでしょう。

ガベージファーストGC(G1GC)

最後にG1GCですが、これまでの3つのGCとは異なり、ヒープを「リージョン」と呼ばれる小さい領域に分割して使用するのが特徴です。CMSと同様、アプリケーションと同時に実行できるフェーズもあるため、結果としてレスポンスタイムの短縮が見込まれます。

どのようにGCを使い分けるか

GCの使い分けは、本連載の第3回で解説したように、スループットとレスポンスタイムを考慮します。

まずはじめは、レスポンスタイムの制約の有り無しにかかわらず、デフォルトのGCを選択しましょう。つまり、マルチコア環境ではパラレルGC、シングルコア環境ならシリアルGCになります。これらのGCはアプリケーションのスループットを重視するため、アプリケーションへCPUリソースを多く割り当てられます。

図5 スループット重視のGC
図5 スループット重視のGC

最近ではヒープのサイズが大きくなり、ヒープ内に作成できるオブジェクトの数が増えています。そのため、ヒープサイズに対し使用できるCPUリソースの割合がこれまでと変わらない場合はこれまで同様のGCが見込めますが、ヒープサイズに対して使用できるCPUリソースの割合が少なくなることが多いです。これにより、パラレルGCやシリアルGCでは停止時間が長期化し、レスポンスタイムの要件を満たせないことがあります。

図6 パラレルでは停止時間が長くなる
図6 パラレルでは停止時間が長くなる

マルチコア環境において、パラレルGCではレスポンスタイムの要件が満たせない場合に、コンカレントであるCMSやG1GCを試してみましょう。

CMSやG1GCにするとスループットが低下する恐れがあるため、システム全体のスループット要件を満たせなくなるかもしれません。その場合は、スケールアップやスケールアウトによってリソースを追加するか、チューニングによって、レスポンスタイムとスループットの兼ね合いをとりましょう。

図7 レスポンスタイム重視のGC
図7 レスポンスタイム重視のGC

まとめ

これまで、一般的なヒープやGCの話から、HotSpot JVMがどのような実装をされているかをご紹介していきました。

すべての処理に対して1つの正解が存在するわけではありません。

まずは、実行する処理の特徴を理解しましょう。そして、使用するJVMにはどのような実装がされているのかを把握してください。

それらを組み合わせて、処理に最適なGCを選択することが重要になります。

おすすめ記事

記事・ニュース一覧