* JavaVMのチューニングメモ [#qdcbd2e1]

#setlinebreak(on)

*** ヒープ領域の構造 [#jc8f72c1]

ヒープ領域は、下図のようにPermanent、New/Old領域に分けられる。
New領域はさらにEden領域とSurvivor領域に分けられる。
また、Survivor領域は、さらにFrom、To領域に分けられる。

|Permanent領域|>|>|>|New/Old領域|
|~|>|>|New領域|Old領域|
|~|Eden領域|>|Survivor領域|~|
|~|~|From領域|To領域|~|

各領域の役割、使用用途は下記の通り。

|領域|説明|h
|Permanent領域|クラスの静的情報が配置される領域。(メソッド定義、フィールド定義、定数、および static 宣言されているフィールドの値など)|
|New/Old領域|生成されたオブジェクト(インスタンス)が配置される領域。ここがGCの対象になる。|
|Eden領域|生成されたオブジェクトが最初に配置される領域。|
|Survivor領域|ScavengeGCを生き残ったオブジェクトがここに移動される。|
|From|次のGC時にTo領域になる。(FromとToが入れ替わる)|
|To|ScavengeGCを生き残ったオブジェクトが最初に移動される領域|
 ※JSPは、クラスを動的にロードする為、JSPを動作させているJava VMのPermanent領域の使用量は動的に増える。


*** 基本的なGC [#d9bf05bf]

- ScavengeGC(マイナーGC)
・NEW領域のみを対象とした短時間で終了するガベージ・コレクションであり、頻繁に実施される。
・前回のScavengeGC時のFrom領域とTo領域は互いに入れ替わる。※1
・ScavengeGCを生き残った回数が、しきい(※2)値を上回るオブジェクトについて、OLD領域への移動を行う。 
 ※1 前回のScavengeGCでオブジェクトの移動先とされたTo領域は、次回のScavengeGCではFrom領域として扱われ、
    このFrom領域とEden領域にある使用中のオブジェクトが、再びTo領域に移動される。
 ※2 しきい値はVM起動オプション -XX:MaxTenuringThreshold で指定可能。

- FullGC(メジャーGC)
・NEWとOLD両方の領域を対象とした大がかりなガベージ・コレクションであり、比較的低い頻度で実施される。
・FullGCが行われている間は、アプリケーションのスレッドは停止される。
・パーマネントがいっぱいになったときもフルGCが実行される。


*** コンカレントGC [#w76c7b76]
 コンカレントGCはJ2SE 1.4から使用できるGC方式で、Old世代のGCをアプリケーションスレッドと並列に実行する。

#html(<div style="background:#f0f0f0;margin-left:20px;padding:0px 5px 5px 5px;">)
◆コンカレントGCの問題点
 ・コンカレントGC実行中はGCスレッドが動作している分、負荷が高くなる為、
  全体的なスループット(ある単位時間当たりの処理能力)は下がり、応答時間も遅くなる。
 
 ・コンカレントGCでは、New世代領域に関連するオプションのデフォルト値として「-XX:SurvivorRatio=1024 -XX:MaxTenuringThreshold=0」
  が設定される為、1回のScavengeGCで回収されなかった短命オブジェクトはすぐにOld世代領域に移動してしまう。
  その為、Old領域の使用量が上がりやすくなり、FullGCの回数が増えてしまう。

 → チューニングが必要。(VMオプションを参照)
#html(</div>)


*** VMオプション [#q07af03c]

ヒープサイズのオプション
|パラメータ名|説明|デフォルト値|h
|-Xms|最小ヒープサイズを設定する|-Xms2M|
|-Xmx|最大ヒープサイズを設定する|-Xmx64M|

GCのオプション(デフォルトはOSごとに異なる為、”一般的”と思われる値を記載)
|パラメータ名|説明|デフォルト値|h
|-XX:NewSize(-Xmn)|New世代領域に割り当てるサイズを指定。(サイズで指定)||
|-XX:MaxNewSize|New世代領域の最大ヒープサイズを設定する||
|-XX:NewRatio|New世代領域に割り当てるサイズを指定。(Old世代領域との比率で指定)||
|-XX:SurvivorRatio|Eden領域とSurvivor領域のサイズを比率で指定&br;※Eden領域のサイズをFromまたはTo領域のサイズで割った値(FromとTo領域は同じサイズ)|8?(EdenはFrom/Toの8倍)&br;コンカレントGCを使用時は1024|
|-XX:MaxTenuringThreshold|New世代領域で、この値で指定する回数のマイナーGCを超えて生き残るとOld世代領域に移動する	|コンカレントGCを使用時は 0|
|-XX:TargetSurvivorRatio|Survivor領域がいっぱいと判断される使用率|50%|
|-XX:+UseConcMarkSweepGC|コンカレントGCの有効化||
|-XX:+CMSParallelRemarkEnabled|メジャーGCのRemarkフェイズをマルチスレッドで実行||
|-XX:+UseParNewGC|マイナーGCをマルチスレッドで実行||
|-XX:PermSize|Permanent領域の初期サイズ|1MB|
|-XX:MaxPermSize|Permanent領域の最大サイズ|64MB|
|-XX:+PrintGCDetails|GCログの詳細を出力する||
|-Xloggc:ファイルPATH|GCログを指定したファイルに出力する||
|-verbose:gc|GCログを出力する||


** チューニングのコツ [#q07af03c]
-- 初期サイズと最大サイズを同じにする事で、サイズ調整にかかるコストが軽減される場合が多い。
-- コンカレントGC、パラレルGCを使用し、GCパラメータを適切に設定する。(コンカレントGCのデフォルト値だとマズい)
-- GCが疑わしい場合は Java起動オプション(-verbose:gc)でGCログを取得する。※HP JVMの場合-Xverbosegc が使える。

#html(<div style="background:#fffddb;margin-left:20px;padding:0px 5px 5px 5px;">)
《参考ページ》
- Javaパフォーマンスチューニング
-- http://www.atmarkit.co.jp/fjava/index/index_devedge.html
-- http://www.atmarkit.co.jp/fjava/rensai4/trouble_knowhow04/01.html
-- http://www.atmarkit.co.jp/fjava/rensai4/troublehacks02/troublehacks02_1.html

- Permanent領域のチューニング
-- http://www.atmarkit.co.jp/fjava/rensai3/devedge06/devedge06_2.html

- コンカレントGC
-- http://www.atmarkit.co.jp/fjava/rensai4/troublehacks02/troublehacks02_1.html

- HotSpot VMとClassic JVM
-- http://www.atmarkit.co.jp/fjava/rensai3/devedge06/devedge06_1.html
#html(</div>)

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS