☕
Javaのメモリ管理まとめ
Java8以降のメモリ管理についてまとめる
二つのメモリ領域
JAVAがメモリ管理(オブジェクト)
Heap | |||
---|---|---|---|
New(Young) | Old | ||
Eden | Survivor0(From) | Survivor1(To) |
OSがメモリ管理(クラスなどの静的メソッド)
Native memory | ||
---|---|---|
Metaspace | C heap | Thread stack |
Heap
Javaプログラムのリソースを管理する領域。New領域とOld領域で構成されている
New領域には三つのメモリ領域が存在し、それぞれの詳細は以下の通り
-
Eden
最初に割り当てられるメモリ領域 -
Survivor0, Survivor1
GC後に解放されず、かつOldには行かないデータ割り当てられるメモリ領域 -
Old
指定回数GCを経験して解放されなかったデータが割り当てられるメモリ領域
Native memory
OSが管理するメモリ領域
-
Metaspace
Javaのクラス、メソッドなど、永続的に参照される
静的オブジェクトを管理するメモリ領域
上限設定がない場合は、OS が扱える上限まで使用可能
(旧parmanent領域,PermGen (Permanent Generation)) -
C heap
JavaVM自身のリソースを管理するメモリ領域 -
Thread stack
スレッド毎に命令の順序をスタックするメモリ領域
1スレッドにつき1スタックが必要。スタックはデフォルトでは1MBが
割り当てられる
GCとは
Garbage collectorの略
実行中のプログラムが占有していたメモリ領域のうち不要になったものを自動的に解放し、空き領域として再利用できるようにする
GCの種類
- MinorGC
Edenの容量が埋まったら発生
特定回数GC対象になるとOldに移動させる - FullGC
Oldに割り当てが失敗したタイミングで、old及びnew(young)のメモリを解放
Java Option
GC,ヒープに関連するものを抜粋
以下のコマンドで使用できるオプションを参照可能
java -X
- Xnoclassgc
クラスのガベージ・コレクションを無効にする - -Xincgc
増分ガベージ・コレクションを有効にする - Xms<size>
Javaの初期ヒープ・サイズを設定する - -Xmx<size>
Javaの最大ヒープ・サイズを設定する - -Xss<size>
Javaのスレッド・スタック・サイズを設定する
Java -Xで確認できないが、metaspaceの上限設定として、いくつかソースがある設定方法
- XX:MaxMetaspaceSize
MetaSpaceの上限を設定
ヒープサイズの確認方法
- jconsole
- jstat
- jmap
などいくつか確認方法があるが、jstatでの確認方法に関して詳細に記載する
ヒープに関するオプション情報は以下の通り
-gc option
ガベージ・コレクションが行われたヒープの統計情報。
S0C: Survivor領域0の現在の容量(KB)。
S1C: Survivor領域1の現在の容量(KB)。
S0U: Survivor領域0の使用率(KB)。
S1U: Survivor領域1の使用率(KB)。
EC: Eden領域の現在の容量(KB)。
EU: Eden領域の使用率(KB)。
OC: Old領域の現在の容量(KB)。
OU: Old領域の使用率(KB)。
MC: メタスペースの容量(KB)。
MU: メタスペースの使用率(KB)。
CCSC: 圧縮されたクラス領域の容量(KB)。
CCSU: 使用されている圧縮されたクラス領域(KB)。
YGC: Young世代のガベージ・コレクション・イベントの数。
YGCT: Young世代のガベージ・コレクション時間。
FGC: フルGCイベントの数。
FGCT: フル・ガベージ・コレクションの時間。
GCT: ガベージ・コレクションの総時間。
公式URL
・jstat
Heap の使用量の計算方法
この中から、上記のヒープに当てはまるものを抽出すると
S0U,S1U,EU,OUとなる。
つまりHeapの合計使用量は
S0U + S1U + EU + OU
Example
以下のコマンドで起動されているjava processを確認し、ID(PID:プロセスID)を取得
ps aux | grep java
#or
jps
jstat -gc {ID}
-gcオプションを用いてmemoryを確認
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT CGC CGCT GCT
21504.0 16384.0 0.0 16352.9 544256.0 105161.4 165376.0 70504.3 71552.0 69756.4 9344.0 8998.5 17 0.206 3 0.287 - - 0.493
ヒープを計算すると
0.0[S0U] + 16352.9[S1U] + 105161.4[EU] + 70504.3[OU]) / 1024 = 187MB
となる。
Serverでのdefaultヒープサイズの確認方法
オプションを指定しない場合、defaultの設定が適用されるが、defaultの設定がよくわからなかったので調査した結果、現状、明文化されたJVMのヒープメモリーの文書は存在しないが、コマンドを使用してデフォルトのヒープサイズを確認することができる。
基本的には物理メモリーの1/4になっていることが確認できた。
What is the default max heap size (-Xmx) in Java 8?
java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'
このように確認できる(約2GB,サーバーメモリーが8GBのサーバーにて)
size_t MaxHeapSize = 2046820352
Discussion