読者です 読者をやめる 読者になる 読者になる

Java Virtual Machine調査方法

Java Virtual Machinenの構成

JVMとOSの領域があります。
JVMはPermanentとHeapがあります。
Permanentはクラスやメソッドなどのメタデーターがロードされる領域になります。
Heapはクラスのインスタンスが格納される領域になります。
JVM以外はOSの領域がありCヒープとSヒープがあります。
CヒープはJavaから利用されるOSライブラリーなどのネイティヴなものがロードされる領域になります。
SヒープはJavaスレッドが格納される領域になります。

f:id:chronos_snow:20161002234440p:plain

各領域に関して

JVM Permanent クラスファイル(メタデーター)がロードされる領域
JVM New Eden 新しいオブジェクトが作成された時に最初に格納される領域
JVM New Survivor From Scavenge GCが発生してTo領域にあるオブジェクトで生存しているものはこの領域に移動
JVM New Survivor To Eden領域が満杯になるとScavenge GCが発生してオブジェクトがこの領域に移動
JVM OLD Scavenge GCが32回発生しても生存しているオブジェクトはこの領域に移動(FullGCで消える)
OS Cヒープ Javaから利用されるOSライブラリーなどのネイティヴなものがロードされる領域
OS Sヒープ Javaスレッドが格納される領域

JVMパラメーターに関して

パラメーター 概要
-Xmx Javaヒープの最大サイズを設定。単位はバイ
-Xms Javaヒープの初期サイズを設定。単位はバイ
-XX:MaxPermSize Permヒープの最大サイズを設定。単位はバイ
-XX:PermSize Permヒープの初期サイズを設定。単位はバイ
-Xmn New領域の初期値および最大値を設定。単位はバイ
-Xss 1スタック領域の最大サイズを設定。単位はバイ
-XX:NewRatio New領域に対する Old領域の割合を設定(2を設定した場合は、New領域とOld領域の割合が、1:2になる)
-XX:SurvivorRatio Survivor領域のFromとToに対するEdenの割合を指定(8を設定した場合は、Eden/From/Toの割合が、8:1:1になる)

Javaプロセス番号確認

[user@localhost]$ sudo su - root
[root@localhost]# sudo -u <アプリケーションアカウント> jps -v
20167 Jps 
15149 sample.jar -Xrs -Xms2048m -Xmx2048m ← この先頭の番号がJavaのプロセスID

ガベージコレクション統計データーの表示(-gcutilオプション)

[root@localhost]# sudo -u <アプリケーションアカウント> jstat -gcutil -h20 <JavaプロセスID> 1000
S0       S1      E           O        M          CCS       YGC   YGCT      FGC    FGCT      GCT  
0.00   0.00  80.09   2.36  97.77  95.62     52    10.822    52   19.085   29.907
0.00   0.00  80.09   2.36  97.77  95.62     52    10.822    52   19.085   29.907
0.00   0.00  80.09   2.36  97.77  95.62     52    10.822    52   19.085   29.907
0.00   0.00  80.09   2.36  97.77  95.62     52    10.822    52   19.085   29.907
0.00   0.00  80.09   2.36  97.77  95.62     52    10.822    52   19.085   29.907

列の見方は下記の内容を参考にして見てください。

概要
S0 Survivor 領域 0 の使用率 (現在の容量に対するパーセンテージ)
S1 Survivor 領域 1 の使用率 (現在の容量に対するパーセンテージ)
E Eden 領域の使用率 (現在の容量に対するパーセンテージ)
O Old 領域の使用率 (現在の容量に対するパーセンテージ)
P Permanent 領域の使用率 (現在の容量に対するパーセンテージ)
YGC 若い世代の GC イベント数
YGCT 若い世代のガベージコレクション時間
FGC フル GC イベント数
FGCT フルガベージコレクション時間
GCT ガベージコレクション総時間|

ガベージコレクション統計データーの表示(-gcオプション)

[root@localhost]# sudo -u <アプリケーションアカウント> jstat -gc -h20 <JavaプロセスID> 1000
S0C            S1C             S0U   S1U   EC                EU                 OC                  OU              MC           MU           CCSC      CCSU      YGC   YGCT      FGC   FGCT      GCT  
262144.0 262144.0  0.0    0.0   1572864.0 1262368.5 1048576.0   24778.0   47488.0 46427.5 5760.0 5507.9     52   10.822  52     19.085   29.907
262144.0 262144.0  0.0    0.0   1572864.0 1262368.5 1048576.0   24778.0   47488.0 46427.5 5760.0 5507.9     52   10.822  52     19.085   29.907
262144.0 262144.0  0.0    0.0   1572864.0 1262368.5 1048576.0   24778.0   47488.0 46427.5 5760.0 5507.9     52   10.822  52     19.085   29.907
262144.0 262144.0  0.0    0.0   1572864.0 1262368.5 1048576.0   24778.0   47488.0 46427.5 5760.0 5507.9     52   10.822  52     19.085   29.907
262144.0 262144.0  0.0    0.0   1572864.0 1262368.5 1048576.0   24778.0   47488.0 46427.5 5760.0 5507.9     52   10.822  52     19.085   29.907

列の見方は下記の内容を参考にして見てください。

概要
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)
PC Permanent 領域の現在の容量 (KB)
PU Permanent 領域の使用率 (KB)
YGC 若い世代の GC イベント数
YGCT 若い世代のガベージコレクション時間
FGC フル GC イベント数
FGCT フルガベージコレクション時間
GCT ガベージコレクション総時間

モリープール世代及び領域容量の表示(-gccapacityオプション)

[root@localhost]# sudo -u <アプリケーションアカウント> jstat -gccapacity -h20 <JavaプロセスID> 1000
NGCMN         NGCMX         NGC             S0C             S1C            EC                  OGCMN         OGCMX          OGC               OC                 MCMN  MCMX            MC            CCSMN  CCSMX          CCSC     YGC   FGC
2097152.0 2097152.0 2097152.0 262144.0 262144.0 1572864.0  1048576.0  1048576.0  1048576.0  1048576.0       0.0 1091584.0  47488.0  0.0        1048576.0  5760.0    52    52
2097152.0 2097152.0 2097152.0 262144.0 262144.0 1572864.0  1048576.0  1048576.0  1048576.0  1048576.0       0.0 1091584.0  47488.0  0.0        1048576.0   5760.0    52    52
2097152.0 2097152.0 2097152.0 262144.0 262144.0 1572864.0  1048576.0  1048576.0  1048576.0  1048576.0       0.0 1091584.0  47488.0  0.0        1048576.0   5760.0    52    52
2097152.0 2097152.0 2097152.0 262144.0 262144.0 1572864.0  1048576.0  1048576.0  1048576.0  1048576.0       0.0 1091584.0  47488.0  0.0        1048576.0   5760.0    52    52

列の見方は下記の内容を参考にして見てください。

概要
NGCMN New 世代の最小容量 (KB)
NGCMX New 世代の最大容量 (KB)
NGC New 世代の現在の容量 (KB)
S0C Survivor 領域 0 の現在の容量 (KB)
S1C Survivor 領域 1 の現在の容量 (KB)
EC Eden 領域の現在の容量 (KB)
OGCMN Old 世代の最小容量 (KB)
OGCMX Old 世代の最大容量 (KB)
OGC Old 世代の現在の容量 (KB)
OC Old 領域の現在の容量 (KB)
PGCMN Permanent 世代の最小容量 (KB)
PGCMX Permanent 世代の最大容量 (KB)
PGC Permanent 世代の現在の容量 (KB)
PC Permanent 領域の現在の容量 (KB)
YGC 若い世代の GC イベント数
FGC フル GC イベント数

メモリダンプ確認方法

[root@localhost]# sudo -u <アプリケーションアカウント> jmap -dump:format=b,file=heap.bin <JavaプロセスID>
[root@localhost}# jhat heap.bin ← http://<ホスト名>:7000でアクセスできる。

メモリダンプテキスト出力方法

[root@localhost]#  sudo -u <アプリケーションアカウント> jmap -histo:live <JavaプロセスID> > heap01.txt

Cヒープ内容出力方法

[root@localhost]# ps -aux | grep 'java'
root     13386  0.0  0.0 175120  1532 ?        S    Sep21   0:00 sudo -u sample nohup /usr/local/jdk/bin/java
sample    13387  0.2 74.9 5969548 3036976 ?     Sl   Sep21   5:05 /usr/local/jdk/bin/java -Xms3072m -Xmx3072m -Xmn2048m
[root@localhost]# gcore <プロセス番号>
Saved corefile core.13386
[root@localhost]# strings -a core.13386 > core.txt
[root@localhost]# sort core.txt | uniq -c | sort -nr | less > data.txt