javaメモリ周り解析方法メモ

  • JVMメモリ/GC状況確認
$ jps | grep -v Jps
12942 
12965 Bootstrap
12812 

$ jstat -gcutil -t <pid> <time>
Timestamp         S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
          489.1   0.00   0.00  79.23  60.00  89.99     62    0.235     3    0.159    0.394
          492.1   0.00   0.00  79.23  60.00  89.99     62    0.235     3    0.159    0.394

=12965

    • 解析
  • gcutil オプション

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

http://docs.oracle.com/javase/jp/6/technotes/tools/share/jstat.html

または実行時にオプションを付与

$ java -XX:+PrintGCDetails Sample

jstatの使い方 | dTblog | デザインとプログラムの境界をさまようブログ


  • ヒープダンプ
    • 取得
$ jps | grep -v Jps
12942 
12965 Bootstrap
12812 

$ jmap -F -dump:format=b,file=<filename> <pid>

=dump.hprof
=12965

    • 解析

Eclipse MAT(Memory Analyzer Tool)

Eclipseで、File > Open File...

JavaVMのメモリ管理に関するまとめ(Javaヒープ、GC、ダンプ等) - ぺーぺーSEのブログ


  • ヒープ統計情報
    • 取得
$ jps | grep -v Jps
19246 Sample

$ jmap -histo 19246

で標準出力に出力される

num #instances #bytes class name

                                                                                          • -

1: 4195417 134237248 [C
2: 4194433 134221856 java.util.HashMap$Entry
3: 4195397 100689528 java.lang.String
4: 4194436 67110976 java.lang.Integer
5: 34 50334752 [Ljava.util.HashMap$Entry;
 ・・・

    • 解析

見たまんまなので解析ツールはいらないかな。
メジャーなツールは特にないっぽい?

PrintClassHistogramツール関係を作成してみた - kotetsu0921のノート
使うとしたらこれかな。


Javaメモリ、GCチューニングとそれにまつわるトラブル対応手順まとめ - 日記のような何か


  • GCログ
    • 取得

起動オプションに下記を設定

- "-verbose:gc"
- "-Xloggc:$CATALINA_HOME/logs/gc.log.${DATE}"
- "-XX:+PrintGCDetails"
- "-XX:+PrintGCTimeStamps"
- "-XX:+PrintGCDateStamps"

で指定した場所にログが吐かれる

    • 解析

GC Viewer
見るべきは右カラムのSummary > Throughput
これはGCによる停止時間を除いたJVM稼働時間の割合。
85%を下回るとヒープサイズをチューニングする必要がある。

Webアプリの問題点を「見える化」する7つ道具 (2/3):現場から学ぶWebアプリ開発のトラブルハック(1) - @IT

目視なら
http://www.whitemark.co.jp/tec/java/javagc.html

  • スレッドダンプ
    • 取得
$ cp ${TOMCAT_HOME}/logs/catalina.out catalina.out_bk

$ kill -3 `pgrep -f "Bootstrap"`

$ diff catalina.out_bk ${TOMCAT_HOME}/logs/catalina.out >> threaddump.${DATE}.${TIME}
    • 解析

ツールは侍を使用

ここでチェックするポイントは以下の点である。

デッドロックが発生していない
・多くのスレッドが同じメソッドで停止している
・多くのスレッドが同じオブジェクトを待っている
・時系列で分析を行い、スレッドの状態が前回のスレッドダンプと同じ状況である

上記のような現象が発生している場合、オブジェクトロック長の問題や、オブジェクトの開放漏れなどによりマルチスレッドの実行が効率的に行えていない。

Webアプリの問題点を「見える化」する7つ道具 (2/3):現場から学ぶWebアプリ開発のトラブルハック(1) - @IT



GC発生状況の目標は下記を参考

マイナーGC、Full GCそれぞれが頻発することなく、かつそれぞれの実行時間を1秒未満に抑えること。

マイナーGCは1秒未満どころではなく、もっと短くなるべき。どれくらいが理想かは?(0.1秒未満ぐらいを目指したい?)

連続した負荷状態(想定されるピークアクセス)でもOutOfMemoryErrorが発生しないこと。

理想的な状態は、上記に加えて、Full GCの発生が低頻度であること。

具体的には、できるだけマイナーGCで短命オブジェクト(1回使ったらもう使わないようなオブジェクト。逆にセッションオブジェクト等は長命オブジェクトとなる)を破棄させて、短命オブジェクトが、TenuringThresholdを超えるマイナーGCを経てNew領域からOld領域へ移動することをできるだけ抑えることがチューニング目標となる。(Old領域に行ってしまうとFull GCでしか掃除されないため、できるだけOld領域に移る前にNew領域で掃除させるということ)(実際のTenuringThresholdが、-XX:MaxTenuringThresholdで指定した値にできるだけ近い状態を維持するということ)

http://d.hatena.ne.jp/learn/20090218/p1