2009年10月30日金曜日

JRockit JVMのGCアルゴリズムとチューニングポイント

Weblogic勉強会@東京でJRockitの話を聞いて、とても参考になったのでメモとして記載しておく。

まずはJRockitのメモリー管理についておさらい
JRockitのJVMのメモリー管理方法(下記を組み合わせて実現する。1+3など)

    1. パラレルGC:すべてのCPUで並行してGCを行う(STOP THE WORLDが発生)
    2. コンカレントGC:特定のCPUでGCを行うため、STOP THE WORLDが発生しない(但し、厳密な意味でのオブジェクトのロック発生の可能性はあり)
    3. シングルスペースGC:mark,sweep,compactionを1つの領域で実現する
    4. 世代別GC:mark,sweep,promotionを世代間で移動しながらメモリ管理を実現する。
  • 処理フェーズ毎の動作

    1. マークフェーズ:ルートセットから参照を辿り、利用中マークを付ける
    2. スイープフェーズ:ヒープを端から操作し、マークのついていないオブジェクトを回収する
    3. コンパクションフェーズ:利用中のオブジェクトを再配置する。
(JNIが利用しているものなどはピンドオブジェクトと言われ移動できない)
上記の処理の動きを"マーク&スウィープアルゴリズム"や"コンパクション"といわれる。
(世代別GCで世代間でオブジェクトを移動する場合は"プロモーション"と呼ぶ)
  • Sun JVMとJRockitの違い

よく言われるのが、JRokitにはPerm領域がないという点である。で、これは正しい。
ただそれだけではない。

JRockitで世代別GCを選択したときJVMのオブジェクトの動きは下記となる。
f:id:cloudcomputing:20091217082023g:image

  • 静的GCと動的GCについて

    1. 静的GC:一般的にはこちらの設定が多い
    2. 動的GC:自ら、上記で挙げたアルゴリズムを選択する。有料の-deterministicというオプションもある。ただ、動的GCはGCのアルゴリズムが変更されるため、GCログがわかりづらくなる点が指摘されている。

■チューニングポイント

1.-Xmx-Xmsは同じ値にする
これは自動的なヒープサイズの拡張コストを抑えるため。

2.32bitOSのプロセスサイズの制限
-Xmx 1500mと指定した場合、ネイティブ領域は500mとなる。この場合ネイティブ領域を思量するアプリケーションの有無を考慮する。

3.コード最適化オプション
自JVM内でのプログラムの性能を絶えず考慮する機能である。但し、APサーバはネットワークの通信がボトルネックとなり、JRockitのコード最適化の恩恵を受けづらい。
(以前は、最適化によるクラッシュもよく出ていた。-XnooptオプションでOFFにしたほうがよい。)

4.LazyUnlockingOption
JDK6.0ではデフォルトで有効。JDK5.0、JDK1.4.2では無効となっている。さまざまな検証結果によると、すべての局面において、有効化したほうがパフォーマンスがよくなる。

5.jrcmdによる運用監視
jrcmdを使用して本番機のメモリ監視を行っている場合、FullGCが発生するケースがある。

特に以下のコマンドは注意。
print_object_summary,heap_diagnostics

対策としては、JMXを使用したMBEANの監視を行うほうがよい。

6.GCアルゴリズムの選択

静的GCでGeneration Pararellがお勧め

7.ナーサリーサイズ設定オプション
世代別パラレルを選択した場合、デフォルトで動的設定となる。但し、サイズ変更によるコストを抑えるため、-Xnsのオプションを定義して設定したほうがよい。

以上

1 件のコメント:

  1. ご指摘ありがとうございました。
    修正いたしました。

    返信削除