JVMのメモリチューニングについて考えてみた。
JVMのJavaVM Optionでメモリのチューニングができる。
オプション | 名称 | 意味 |
---|---|---|
-Xms | ヒープの初期値 | コレだけのメモリはJavaが使用するぞ!と宣言する |
-Xmx | ヒープの最大値 | コレだけメモリ使いたいんです。と宣言する。確保してるわけではない。 |
-Xmn | New領域の最大値 | NEW+OLD+Parmanent=ヒープ領域、GCはNEWを対象とするか、NEW+OLDを対象とするかの2つ |
-XX:PermSize | Permanent領域の初期値 | 主にclassの情報を格納する領域 |
まずメモリについては大きく3つ
若い世代の NEW領域*1
古い世代の OLD領域
そして特にJVMが持つParmanent領域
Parmanet領域はclassのロードとstatic変数、メソッドの格納に関係してる。
ロードするclassの数が増えると注意が必要。稼働中のモジュール入れ替え(動的デプロイ)とかは既存のモジュールのクラスと入れ替えモジュールのクラスが共存する時間帯があるからその分のメモリ確保に気をつける必要がある。
NEW領域について、基本はインスタンスオブジェクトが格納される領域
この領域がいっぱいになるとYoungGC*2が動く。
YoungGCで回収されなかったメモリにしるしをつける。
次にYoungGCが動いたときにまた回収されなかったメモリにしるしをつける。
何回もしてると、特定のメモリにしるしがつきまくるので、そういうやつは
OLDに移動させられる。
OLD領域は比較的安定的な領域だからよく使うオブジェクトを格納していると効率がよい。
で、OldGCが動くのは、New+Oldの空き領域では足りないメモリのオブジェクトを生成しようとしたとき。
例えば Newが10MでOldが20Mこのうち、Oldで使用しているのが6M
そのときに25Mのオブジェクトを生成しようとしたとき。
式だと 25M>10M+(20M−6M) を満たすとき。
まとめ:
パチンコで言うとNEW領域はフィーバー時に下皿に貯まるようなもん。
OLD領域は確率変動中に下皿に少しずつ貯まるようなもん。
でParmanent領域は椅子の後ろに積んでるドル箱みたいなもんかな。
*YoungGCはScavengeGC、OldGCはFullGCのことを指します。
GCに対する定義を加筆・修正しました。