メモリ設定方法
以下の設定を元に考えてみます。
-XX:MaxMetaspaceSize=128m -Xms256m -Xmx256m -Xss1m -XX:NewSize=100m -XX:MaxNewSize=100m
|オプション|説明|設定値目安| |:-|:-|:-|
|MetaSpace|libの読み込み、JSPのコンパイル結果つむ|64~256程度| |Xms|ヒープ領域の最小サイズ(初期サイズ)|XmsとXmxは同じ数値を指定| |Xmx|ヒープ領域の最大サイズ|XmsとXmxは同じ数値を指定| |Xss|Java APIで生成するスレッドのスタックサイズ| |NewSize|ヒープ領域内のNew領域のサイズ指定。XmsのNew領域版| |MaxNewSize|ヒープ領域内のNew領域のサイズ指定。XmxのNew領域版|
Xms Xmx
物凄い大きなMapやListを保持する可能性が無い限りは同じ数値を指定するのが望ましい。
Xmxのサイズを大きい状態だと、FGC発生時に最大でXmxのサイズまで拡張されていく。
メモリの拡張確保分だけ、FGCの停止時間が長くなってしまうため、同じサイズにするのが良いとされている。
Old領域
New領域に指定されなかった残りのヒープ領域はOld領域に割かれます。(Xms - NewSize = Old領域)
New領域は最初にインスタンスが格納される領域で、一杯になるとYGCとかマイナーGCなどのGCが走る。
何回かのYGCを生き残ったインスタンスがOldに移動される。
NewとOldは1:2が基本で、Oldが大きい方が安全です。ほぼOld領域に行かないと分かっている場合は、
1:1運用がFGCが発生し難いので効率がよい。
メモリ設定等を確認するうえで良く使うコマンド
JVMのオプションをjps -vで確認し、
jstat で1秒毎のメモリ状況確認する。
jps -v [user@hostname bin]$ jps -v 11111 Jps -Dapplication.home=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.151-1.b12.35.amzn1.x86_64 -Xms8m 22222 Bootstrap -Dfile.encoding=UTF-8 -XX:MaxMetaspaceSize=64m -Xms80m -Xmx80m -Xss1m -XX:NewSize=40m -XX:MaxNewSize=40m -XX:SurvivorRatio=12 -XX:TargetSurvivorRatio=95 -XX:MaxMetaspaceSize=32m -Dfile.encoding=UTF-8
jps -vはその環境で動作しているJVMの一覧(オプション付き)とプロセスIDを表示可能。
tomcatが動作しているのかの確認にも使用可能。
jstat -gcutil -h{ヘッダ間隔] [プロセスID] [実行間隔] jstat -gccapacity [プロセスID] [実行間隔] [user@hostname bin]$ jstat -gcutil -h20 23436 1000 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 16.46 8.74 45.33 97.03 93.16 865 2.958 1 0.036 2.994 0.00 16.46 11.03 45.33 97.03 93.16 865 2.958 1 0.036 2.994 0.00 16.46 12.72 45.33 97.03 93.16 865 2.958 1 0.036 2.994