HotSpot JVMを使うとき、どのようにGCを設定していますか?
検索して出てきたホームページを見て
「とりあえずこのホームページにあるように最新のGCを指定したし、同じようにオプションを設定したから大丈夫だろ」
と思ってしまう話をよく見聞きします。
しかし、たとえばバッチのようにスループットを意識すべき処理にもかかわらず、レスポンスタイム重視のGCを選んでしまうのは適切ではありません。
最終回となる今回は、HotSpotにはどのようなGCがあり、どのようにそれらを選択すれば良いのかを紹介します。
4つのGCを使いこなす
HotSpot JVMには、以下の4つのGCが実装されています。
- シリアルGC
- パラレルGC
- コンカレント マーク&スイープGC(CMS)
- ガベージファーストGC(G1GC)
1つずつ見ていきましょう。
シリアルGC
このGCの特徴は、ヒープの空き領域が少なくなるとシングルスレッドでマーク&スイープとコンパクションを行うことです。
昔はデフォルトでしたが、マルチコア化が進み、かつヒープサイズが大きくなった今では、GCに時間がかかり、停止時間が長くなってしまうため、積極的に使うことは少ないでしょう(現在も、シングルコア環境ではデフォルトです)。
パラレルGC
マルチコア環境ではこのGCがデフォルトです。
このGCの特徴は、ヒープの空き容量が少なくなると、マルチスレッドでマーク&スイープとコンパクションを行うことです。複数のスレッドでGCすることで、アプリケーションの停止時間がシリアルGCに比べて短くなり、アプリケーションを実行できる時間が長くなります。そのため、スループットが高くなるでしょう。
コンカレント マーク&スイープGC(CMS)
CMSの特徴は、アプリケーションと同時に実行できるフェーズと、アプリケーションを止めて実行するフェーズに分かれていることです。
これらのフェーズのうち、図4の実線部である①initialフェーズと③remarkフェーズのみがアプリケーションを停止させます。
②コンカレントマーク&プリクリーン、④コンカレントスイープ、⑤リセットはコンカレントに実行されるため、アプリケーションと同時に実行されます。
CMSでは、GCで使用するスレッド同士の協調処理などにCPUリソースを使わなければならないため、アプリケーションのスループット低下が見込まれます。しかし、一部のフェーズではアプリケーションを停止する必要がないため、アプリケーション全体の停止時間は短くなります。その結果、GCがレスポンスタイムに与える影響が小さくなるでしょう。
ガベージファーストGC(G1GC)
最後にG1GCですが、これまでの3つのGCとは異なり、ヒープを「リージョン」と呼ばれる小さい領域に分割して使用するのが特徴です。CMSと同様、アプリケーションと同時に実行できるフェーズもあるため、結果としてレスポンスタイムの短縮が見込まれます。
どのようにGCを使い分けるか
GCの使い分けは、本連載の第3回で解説したように、スループットとレスポンスタイムを考慮します。
まずはじめは、レスポンスタイムの制約の有り無しにかかわらず、デフォルトのGCを選択しましょう。つまり、マルチコア環境ではパラレルGC、シングルコア環境ならシリアルGCになります。これらのGCはアプリケーションのスループットを重視するため、アプリケーションへCPUリソースを多く割り当てられます。
最近ではヒープのサイズが大きくなり、ヒープ内に作成できるオブジェクトの数が増えています。そのため、ヒープサイズに対し使用できるCPUリソースの割合がこれまでと変わらない場合はこれまで同様のGCが見込めますが、ヒープサイズに対して使用できるCPUリソースの割合が少なくなることが多いです。これにより、パラレルGCやシリアルGCでは停止時間が長期化し、レスポンスタイムの要件を満たせないことがあります。
マルチコア環境において、パラレルGCではレスポンスタイムの要件が満たせない場合に、コンカレントであるCMSやG1GCを試してみましょう。
CMSやG1GCにするとスループットが低下する恐れがあるため、システム全体のスループット要件を満たせなくなるかもしれません。その場合は、スケールアップやスケールアウトによってリソースを追加するか、チューニングによって、レスポンスタイムとスループットの兼ね合いをとりましょう。
まとめ
これまで、一般的なヒープやGCの話から、HotSpot JVMがどのような実装をされているかをご紹介していきました。
すべての処理に対して1つの正解が存在するわけではありません。
まずは、実行する処理の特徴を理解しましょう。そして、使用するJVMにはどのような実装がされているのかを把握してください。
それらを組み合わせて、処理に最適なGCを選択することが重要になります。