JavaのGCの種別について調べる機会があったので、簡単にまとめてみた。
4種類のGC
以下の4種類のGCがある。
- シリアルGC
- パラレルGC
- コンカレント マーク&スイープGC(CMS)
- ガベージファーストGC(G1GC)
シリアルGC
シングルスレッドでマーク&スイープとコンパクションを行う。
昔はこのシリアルGCがデフォルト、シングルコア環境で利用。
パラレルGC
マルチコア環境ではデフォルト
マルチスレッドでマーク&スイープとコンパクションを行う。
コンカレント マーク&スイープGC(CMS)
GCを二つのフェーズに分け、極力アプリケーションの停止を抑える方法
- アプリケーションと同時にGCを実行するフェーズ
- アプリケーションを止めてGCを実行するフェーズ
スレッド同士の協調処理などにCPUリソースを使うため、アプリケーションのスループット低下が見込まれるが、アプリケーション全体の停止時間が短くなる。その結果GCがレスポンスタイムに与える影響が小さくなる。
CPUの使用率が高い場合、性能が劣る場合がある。その際はパラレルGCを使う。
ガベージファーストGC(G1GC)
ヒープを「リージョン」と呼ばれる小さい領域に分割して使用する。
レスポンスタイムの短縮が見込める。
Java7で追加
4G以上のメモリで最大限の性能が発揮されるように設計されているらしいが、メモリとはヒープメモリのこと?それともVMのメモリのこと?どっちだろう。
GCの歴史
- Java6までのGC
シリアルGC、パラレルGC、CMSの3つ。結局フルGCでOLDとNEW領域両方を掃除するので、ヒープサイズが大きくなるとアプリケーションの停止時間が延びる。まーCMSは短くなるように頑張っているが・・ - Java8まではシリアルGC、パラレルGCがデフォルト
- Java9以降ではG1がデフォルト
使い分け
スループットとレスポンスタイムを考慮する。
- シリアルGC、パラレルGC(アプリケーション停止型)
- シングルコア、マルチコアでのデフォルト(本当?)のGC
- スループット重視、でもGCで止まる時間が長くなるのでレスポンスタイムの要件を満たせないことがある。
- CMS、G1GC(アプリケーションと並行でコンカレント処理型)
- マルチコア環境において、パラレルGCではレスポンスタイムの要件が満たせない場合に選択
- スループットが低下する恐れがある