2014年1月28日火曜日

jmapを用いたJVM Heapの状態調査

メモ。
参考:http://www.javainthebox.net/laboratory/JavaSE6/managementtools/mngtools.html

jmapは、JVMのHeapメモリ内の情報をdumpするためのツールです。
http://docs.oracle.com/javase/jp/6/technotes/tools/share/jmap.html
引数にjavaのプロセスIDを渡してあげると、当該プロセスのメモリ情報をダンプすることができます。
jmap -dump:format=b,file=[file name] [pid]
上記の例では、バイナリ形式でheapのダンプ情報を出力します。
ダンプしたファイルは色々なツールで可視化が可能ですが、javaの標準コマンドであるjhatが一番楽だと思います。
jhat [file name] 
引数のファイルには、上述のjmapで出力したダンプファイルを指定します。
このように指定してあげると、デフォルトでは7000番のポートでサーバーが立ち上がり、ブラウザで接続すると以下のような分析画面が表示されます。

お察しの通り、上記はJettyの起動プロセスからjmapでダンプした結果を可視化したものです。
解析画面にはいくつか項目があり、そのうち画面下部の「Heap Histogram」を選択するとHeap上に存在するインスタンスの数とバイトサイズを確認することができます。


このように、jmapは手軽にJVMのHeapの状態を確認するには便利なのですが、すべてのデータをダンプすると、JVMのHeap Sizeによってはダンプファイルのサイズが非常に大きくなり、解析が難しくなります。
僕の例だと、数GBのダンプファイルをjhatで読み込ませようとしたら、30分くらい解析に時間がかかった結果最終的にOutOfMemoryでプロセスが死にました。。。

たとえばHeap Histogramだけを知りたい、という場合、以下のオプションを指定してあげるとjhatの上記の例で表示したのと同じようなデータが取得できます。
jmap -histo [pid] > [file name]
結果は以下

なお、以下のように「live」オプションを付与すると、生存中のオブジェクトについてのみ結果出力されます。
jmap -histo:live [pid] > [file name]

0 件のコメント:

コメントを投稿