この記事は Java Advent Calendar 2014 の一日目の記事です。
先日の JJUG CCC 2014 Fall で CMS GC について話してきました。
結構遅めの時間帯にも関わらず、200人規模の部屋がいっぱいに埋まるぐらいの盛況振りで、みなさんGCにお困りなんだなあと実感しました。スライドは以下に公開しています。CMS GC の挙動から GC ログの読み方、どういうケースが厄介なのかを紹介しているので是非ご覧ください!
嬉しいことにセッションの反応は良かったのですが、「遅めの時間帯で頭も疲れてるとガチ話辛い」という声もあったので、今回は CMS GC について比較的重要な点についてだけ簡単におさらいしたいと思います。
オプションについて
@nekop さんの「Java 7 CMS GCの基本的な情報の整理 - nekop's blog」を読めば OK 。
上の記事から追記するとしたら
- -Xmx と -Xms は同じ値にしたほうが、拡張/シュリンク時に Major GC などの負荷が発生しないのでお勧め。
- -XX:+CMSClassUnloadingEnabled は JDK8 でデフォルト True なので、もう True で良いと思う。
他、CMS GC の発生条件のチューニングとして、以下のスライドで CMSInitiatingOccupancyFraction と UseCMSInitiatingOccupancyOnly を紹介しました。
UseCMSInitatingOccupancyOnly を使わずに、チューニングすることも可能ですが、自分が知っている限りでこれが無効の場合の CMS GC 開始条件は、
- CMS 実行間隔の統計的に、今実行しないとヒープが不足すると判断された場合
- 最初の CMS 実行時に、ヒープ使用率が CMSBootstrapOccupancy で指定した値を超えていた場合
- ヒープ領域拡張した結果、GC を行わなくてもメモリ確保に成功した場合
- 断片化によってまとまったメモリ空間の確保に失敗すると判断された場合
と、これ以外(インクリメンタル CMS やパーマネント領域関係とか)にもあるのでここら辺を一つ一つやるよりは UseCMSInitiatingOccupancyOnly で調整したほうが楽です。
GC ログの読み方について
GC ログの読み方はスライドの P.37 以降に一つ一つ書いているのでそちらで!
特に重要そうな点は以下の通りです。
おわりに
CMS GC ではパフォーマンス的にどうにもならない時もあります。どうにもならないことが掴めたら G1GC や Parallel GC、Azul Zingを使うことを検討しましょう。
これ以外にも OpenJDK にはまた新しい GC として G1GC リプレース型の Pauseless GC である Shenandoah がやってきます。JavaOne2014 でも発表していましたが、資料はこっちの方(「Shenandoah An ultra-low pause time Garbage Collector for OpenJDK」)が解りやすいかな。Remembered set絡みの処理が早くなるアイデアで、G1GC より停止時間が優れてる感じっぽいと受け取りましたが、出てくるのはしばらく後ですね。こんな感じで GC との付き合いはしばらく続きそうです。