Archive for 10月, 2009

10月 12th, 2009

コンカレントGCの注? ?

Posted in Java, Tomcat by admin

 次? 代のサーバマシンによるシステムでは、CPUマルチコア化が進み、OSぜ 64bit化によってメモリも豊富に眩 むような大規模なものが一般的になるのではないでしょうか。このようなサーバ上ぜ Tomcatを起動させる場合、その? 富なリソースを生かしぜ Javaのヒープサイズ、GCチューニングを実施するのが一般的だと思゜ れます。ただし、このオプションを中途半端に? ? すると、逆にパフォーマンスを損なう可能性があることに注? しなければならないようです。

 CPUマルチコアリソースを十分に活用する為ぜ GCチューニングパラメータに、「-XX:+UseParNewGC」「-XX:+UseConcMarkSweepGC」があります。前者ぜ GC処理をマルチCPUでパラレルに? 施するオプション、「-XX:ParallelGCThreads=n」と合゜ せてパラレル処理? (n)を指定出来ます。また、後者は、アプリケーションスレッドと並行しぜ GCを処理可能とするオプションです。アプリケーションスレッドと並行で? 行するGCをコンカレントGCと呼びます。シングルスレッド環? ではフボ GC実行時に? 全にアプリケーションが停止していた事(”Stop The World”)を考えると、マルチCPU環? では特に有用な? 能だと思゜ れます。

 しかし、コンカレントGCオプションを使用しているにも関゜ らず、アプリケーションが圏 応しなぜ なったり、Tomcat起動時から徐々にコンカレントGC回数が増加しいぜ ように? えることがありました。このケースについての調査してみました。

§ コンカレントGCの? 癜

 コンカレントGCを使用している場合、GCログにぜ “Full GC”という表示があまり出ていないので、GC処理関連に問題はないかように? えてしまう場合があります。しかし、コンカレントGCぜ GCログぜ “Full GC”として出力されないだけで、処理としてはフボ GCと? ゜ らない負? /処理時間を伴うOld世代のメジャボ GCです。GC Viewer等でみると、コンカレントGCもフボ GCとして朏 画されていることが゜ かります。コンカレントGC発生時ぜ GCログは以下のようになっています。

[GC [1 CMS-initial-mark: 1358402K(1474560K)] 1376938K(2034944K), 0.0230380 secs] [Times: user=0.02 sys=0.00, real=0.03 secs]
[CMS-concurrent-mark-start]
[CMS-concurrent-mark: 1.989/1.989 secs] [Times: user=2.43 sys=0.03, real=1.98 secs]
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.009/0.009 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
[CMS-concurrent-abortable-preclean-start] CMS: abort preclean due to time
[CMS-concurrent-abortable-preclean: 0.786/5.094 secs] [Times: user=2.04 sys=0.06, real=5.10 secs]
[GC[YG occupancy: 217078 K (560384 K)]
[Rescan (parallel) , 0.0803410 secs]
[weak refs processing, 0.0033110 secs]
[1 CMS-remark: 1362083K(1474560K)] 1579161K(2034944K), 0.0838390 secs] [Times: user=0.17 sys=0.00, real=0.08 secs]
[CMS-concurrent-sweep-start]
[CMS-concurrent-sweep: 0.582/0.582 secs] [Times: user=0.70 sys=0.00, real=0.59 secs]
[CMS-concurrent-reset-start]
[CMS-concurrent-reset: 0.010/0.010 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]

コンカレントGCフェーズ?
CMS-initial-mark (0.03秒) 並? コレクションサイクルの開始
CMS-concurrent-mark (1.98秒) 並? マーキング段障 の? ゜ りを示す
CMS-concurrent-preclean (0.01秒) 並? 実行が可能な? 前クリーニング段障 を示す
CMS-concurrent-abortable-preclean (5.10秒) concurrent-precleanぜ remarkの間で? 行する処理
CMS-remark (0.08秒) Concurrent Markフェーズで? 施したマーキングの整合性を確? する
CMS-concurrent-sweep (0.59秒) 並? スウィープ段障 の? ゜ りを示す
CMS-concurrent-reset (0.01秒) 最終段障 を示す(次の並行コレクションの机 備)

“ initial-mark, remarkは全アプリケーションスレッドを停止を伴う

http://www.sun.com/bigadmin/content/submitted/cms_gc_logs.html

 上記1回のコンカレントGCだけ見ても8秒以? の時間が経遜 しており、この間1つぜ CPUが独占されている状態になります。この並行処理のオーバーヘッドにより、アプリケーションのスループットの? 下につながります。つまりフボ GCによるアプリケーション停止の代償がコンカレントGCによるスループット作 下ということです。

 さらに注? しなければならないのは、コンカレントGCオプション「-XX:+UseConcMarkSweepGC」を使用した場合、New世代領域のオプションデフォルト値が「-XX:SurvivorRatio=1024 -XX:MaxTenuringThreshold=0」に自動設? されるという点です。「-XX:MaxTenuringThreshold=0」によって、1回のマイナボ GC後に卜 Old領域に移動してしまう。結果として、Old世代領域の使用釜 が上がりやすぜ なりコンカレントGCの回数が徐々に? えていぜ ことになります。従って、コンカレントGCを使用する場合、同時ぜ New世代領域のチューニングパラメータを付加する必要があるようです。以? のパラメータを追加検? します。

§ -XX:+UseConcMarkSweepGCと同時設? したいパラメー゜

-XX:+CMSParallelRemarkEnabled
CMS-remarkの停止時間を短縮することができる。
動作させるマシンぜ CPUが2個以? かつ物理メモリが2Gbytes以? の場合には、自動設? される。

-XX:SurvivorRatio=8
Eden領域ぜ Survivor領域のサイズを比? で指定。
コンカレントGC使用時に自動設? される”Survivor:Eden=1:1024″を”Survivor:Eden=1:8″に矯正。

-XX:TargetSurvivorRatio=90
Survivor領域がいっぱいと判断される使用? 。
Survivor領域ぜ 90%が使゜ れるまで、Old世代領域に移動いかないように判断される。

-XX:MaxTenuringThreshold=31
New世代領域において、オブジェクトがこの値で指定する回数のマイナボ GCを超えて生き残ると、Old世代領域に移動。
コンカレントGC使用時に自動設? される”0″を31に矯正。

全て眺 めると以下のようなオプション? 覧となりました。

-Xmx(物理メモリサイズから割? )
-Xms(物理メモリサイズから割? )
-Xmn(物理メモリサイズから算出、Xmxぜ 4分ぜ 4以? 、CPU数に? じて? 加)
-Xss(物理メモリサイズから算凜 )
-XX:PermSize=(物理メモリサイズとアプリ? 様から検? )
-XX:MaxPermSize=(PermSizeと同? )
-XX:+UseParNewGC
-XX:ParallelGCThreads=(CPUコア数以下)
-XX:+UseConcMarkSweepGC
-XX:SurvivorRatio=8
-XX:TargetSurvivorRatio=90
-XX:MaxTenuringThreshold=31