Java GC周りの動きを復習しておく。
New Old(Tenured) Permanent
---------------------------------------------------
| | | | | |
---------------------------------------------------
Eden Survivor0
Survivor1
New = Eden + Survivor0 + Survivor1
Survivor領域はそれぞれFrom、To領域とも言われる。
Survivor0と1はGCごとにFromとToが交互に入れ替わる。
Permanent領域にはJVMにロードされるクラスやメソッドの情報が入る。
多数のクラスを動的に生成させたりしなければ、大きく変化しない。
◆ GCの動作概要
GCの種類は大きく2つある。
簡単な例で動きを追ってみる。
● New領域のためのGC(マイナーGC)
1. 新規オブジェクトがEden領域に格納される。
2. Eden領域が一杯になると、New領域でマイナーGCが発生。
3. マイナーGC完了後、生存オブジェクトがSurvivor領域の片方へ移動。
4. 次にマイナーGCが走った場合は、
Eden領域の新規オブジェクトと、1回目のGCで格納した
Survivor領域の片方へ移動したオブジェクトが対象となる。
このGCで生き残ったオブジェクトがSurvivor領域のもう片側へ移動する。
5. 3と4を繰り返し、
Survivor領域が閾値以上になるか、
Survivor領域でX回GC実行後も回収されない場合、
生存しているオブジェクトはSurvivor領域からOld領域へ移る。
● New領域とOld領域を含めたFull GC(メジャーGC)
6. Old領域が設定した閾値になるとすべての領域でFull GCが発動。
※Permanent領域が不足してもFull GCが動く。
◆ GCの動作方式
● シリアルGC
GCを1スレッドで実施する。
-----→ -----→
-----→ -----→
-----→ -----→ -----→
-----→ -----→
-----→ -----→
通常処理 GC 通常処理
GCのために複数スレッドを利用できる。
-----→ -----→
-----→ ----→ -----→
-----→ ----→ -----→
-----→ ----→ -----→
-----→ -----→
通常処理 GC 通常処理
-XX:+UseParallelGC
パラレルGCを有効
-XX:+UseParallelOldGC
ディフォルトではNew領域のGCのみに対して適用されるが
オプションでFull GCにも適用。
-XX:ParallelGCThreads
各並列実行時のスレッド数の設定
● コンカレント(並列)GC
Full GC時に利用できる以下の方式である。
initial markとremark時にのみ通常処理が停止する。
通常処理
-----→ -----→ -----→
-----→ -----→ -----→
-----→ -----→ -----→
-----→ -----→ -----→
-----→ -----→ -----→
initial
mark remark
-----→ -----→
-----→ -----→ -----→ -----→
-----→ -----→
concurrent concurrent
mark sweep
Full GCの実行方式をコンカレントGC化
-XX:CMSInitiatingOccupancyFraction
Old領域のGC実行の閾値
-XX:+UseCMSInitiatingOccupancyOnly
CMSの稼働制御
CMSInitiatingOccupancyFraction に達したときだけCMSを稼働
-XX:CMSParallelRemarkEnabled
オブジェクトのremakフェイズをマルチスレッド化
New領域でパレレルGCを有効
-XX:+UseParallelGC ではないので注意
-XX:ParallelGCThreads
各並列実行時のスレッド数の設定
各並列実行時のスレッド数の設定
◆ その他、知っておくべきチューニングキー
-Xms
初期ヒープサイズ
-Xmx
ヒープサイズ全体値
-Xmn(-XX:NewSize)
New領域初期サイズ
-XX:MaxNewSize
New領域の最大サイズ
-XX:SurvivorRatio
Eden領域とSurvivor領域の割合
-XX:TargetSurvivorRatio
Survivor領域がいっぱいと判断される使用率
-XX:NewRatio
New領域とOld領域の割合
-XX:PermSize
Permanent領域最大サイズ
-XX:MaxPermSize
Permanent領域初期サイズ
-XX:SurvivorRatio
New領域内のEden領域とSurvivor領域の設定
ディフォルトは8
Eden : Survivor0 + Survivor1 = 2:8
-XX:TargetSurvivorRatio
Survivor領域の容量の閾値
Survivor領域のX%を超えた場合、
Survivor領域に含まれるオブジェクトをOld領域へ移動させる
大きな値にするとOld領域へ移動させずらくできる
-XX:MaxTenuringThreshOld
Survivor領域からOld領域に移動させるときのGC回数の閾値
X回GCによって生存しているオブジェクトがOld領域へ移動
-XX:+UseThreadPriorities
-XX:ThreadPriorityPolicy
スレッドプライオリティの有効化と、
スレッドのプライオリティの制御
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintClassHistogram
-XX:+PrintTenuringDistribution
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintPromotionFailure
-XX:PrintFLSStatistics
-Xloggc:/imail/meta/metadata/log/cassmeta_gc.log"
ログ出力関係
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/var/crash-`date +%s
メモリ不足時のダンプ出力
-XX:+UseNUMA
NUMA(Non-Uniform Memory Access)を考慮したメモリ配置を実施
◆ 統計
GCの動作をモニタリングするために、
jstatの結果から動きをグラフ化しておくとよいだろう。
# jps
12345 HogeDaemon
# jstat -gcutil 12345
S0 S1 E O P YGC YGCT FGC FGCT GCT
25.05 0.00 26.16 45.39 59.82 49475 28076.939 3606 2046.980 30123.919
(見方)
S0 : Survivor space 0 utilization as a percentage of the space's current capacity. (%)
S1 : Survivor space 1 utilization as a percentage of the space's current capacity. (%)
E : Eden space utilization as a percentage of the space's current capacity. (%)
O : Old space utilization as a percentage of the space's current capacity. (%)
P : Permanent space utilization as a percentage of the space's current capacity. (times) ※
YGC : Number of young generation GC events. (times) ※
YGCT : Young generation garbage collection time. (ms) ※
FGC : Number of full GC events. (times) ※
FGCT : Full garbage collection time. (ms) ※
GCT : Total garbage collection time. (ms) ※
※ は瞬間値ではなく、積み上げ値(前回からの加算値)である
・速度観点
YGCの回数に対してYGCTのかかった時間が1回3秒以下: YGCT/YGC < 3.0)
FGCの回数に対してFGCTのかかった時間が1回3秒以下: FGCT/FGCT < 3.0)
※差分データがあればもちろんそれでもよい
・容量観点
各領域の使用容量推移: S0、S1、E、O が設計意図通りか
● GCがどのように発生しているのかグラフで視認できるツールとして
gclog + GCViewがある。
● JVMの起動オプションに-Xloggc:[file]をつけ、そのログファイルをgcviewerツールで表示するとJVMのメモリ状態を追いやすくなる。
● javaスレッドのスタックトレースを表示させるには、jstackも有用である。
日本ではGC関連の書籍は実質これしかない。
うん?中古しかない?
絶版だが間違いなく良本である。