Java Flight RecorderとMission Controlのまとめ
Java Flight Recorder(以下JFR)はいわゆるJavaプロセスのプロファイラ。
Java Mission Control(以下JMC)はJFRで取得したプロファイリングデータをGUIで見る事ができるビューア。
もともとはJRockitで搭載されていたのが, Java 7 Update 40以降で搭載されるようになった。
詳しくは
http://www.infoq.com/jp/news/2013/10/misson-control-flight-recorderHotSpot JVMで動作するMission ControlとFlight Recorder
で。
この機能は商用ライセンスのみになっているので、プロダクト用に利用する場合は商用ライセンス契約が必要。
ただし、JVMのオプションを指定することで利用できるようになっているのでお試しで利用することはできるみたい。
使い方は基本的には
http://docs.oracle.com/javase/8/docs/technotes/guides/jfr/toc.htmlTable of Contents
に全てが書いてあります。
プロファイリングの開始
$ java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=duration=60s,filename=myrecording.jfr MyApp
のようにプロセス起動時に開始するか
$ java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder MyApp
で起動してから
jcmd(後述)でJFR.startコマンドを投げることによって開始される。
プロファイリング開始後の操作
jcmdコマンドを使ってjavaプロセスにコマンドを投げることによって、プロファイラに命令を送ることができる
#javaプロセスの確認 $ jcmd 3857 ←プロファイリングしたいプロセス 20762 sun.tools.jcmd.JCmd #このプロセスに投げることができるコマンド一覧の確認 $ jcmd 3857 help 3857: The following commands are available: JFR.stop JFR.start JFR.dump JFR.check VM.native_memory VM.commercial_features ManagementAgent.stop ManagementAgent.start_local ManagementAgent.start Thread.print GC.class_histogram GC.heap_dump GC.run_finalization GC.run VM.uptime VM.flags VM.system_properties VM.command_line VM.version help
プロファイリングスタート
$ jcmd 3857 JFR.start 3857: Started recording 1. No limit (duration/maxsize/maxage) in use. Use JFR.dump recording=1 filename=FILEPATH to copy recording data to file.
recordingという番号がプロファイリング開始番号みたいな扱いらしい。
duration(期間)などの指定もオプションでできる
プロファイリングの状態の確認
$ jcmd 3857 JFR.check Recording: recording=1 name="Recording 1" (running)
recording番号は1でプロファイリング実行中(runnning)というのが確認できる
プロファイリングデータのダンプ取得
$ jcmd 3857 JFR.dump filename="/tmp/myprofile.jfr" compress=true recording=1
filenameでダンプファイルのパスを指定して、zipでの圧縮がしたければcompress=trueを指定する。
recorindg番号を指定は必須
プロファイリングの終了
$ jcmd 3857 JFR.stop recording=1
これもrecorind番号は必須
JMCの起動
$ [JDK_PATH]/bin/jmc
で起動
JMX経由の情報も見ることができるが、今回はプロファイリングデータから読み込むのでメニューのファイルから開くで、ダンプした/tmp/myprofile.jfrを指定する。
時系列ごとによく使われいてるMethodやThreadの一覧、メモリの割り当て状況やIO(ファイルやネットワーク)の状況も全て解析できる。
プロファイリング対象の設定
デフォルトのプロファイリングの設定だとメモリの割り当て状況(Memory -> Allocations)やヒープのオブジェクト解析(Memory -> Object Statistics)がオフになっているので、有効にする。
(JMCでウィンドウ開いてもEvent type 'Allocation in new TRAB' is not enabled in this recordingとかEvent type 'Object Count' is not enabled in this recordingとか出て何もグラフに表示されない)
ちなみにTLABはThread Local Allocation Buffersの略。
$ls -l [JDK_PATH]/jre/lib/jfr -rw-rw-r-- 1 root wheel 18574 Oct 8 2013 default.jfc -rw-rw-r-- 1 root wheel 18531 Oct 8 2013 profile.jfc
これがプロファイリング用の設定ファイルらしい
とりあえずdefault.jrcをmyprofile.jfcとしてコピーして必要そうなところをfalse -> trueに書き換えて有効にする
$ diff default.jfc myprofile.jfc 118c118 < <flag name="class-loading-enabled" label="Class Loading">false</flag> --- > <flag name="class-loading-enabled" label="Class Loading">true</flag> 237c237 < <setting name="enabled" control="heap-statistics-enabled">false</setting> --- > <setting name="enabled" control="heap-statistics-enabled">true</setting> 267c267 < <setting name="enabled">false</setting> --- > <setting name="enabled">true</setting> 446c446 < <setting name="enabled" control="allocation-profiling-enabled">false</setting> --- > <setting name="enabled" control="allocation-profiling-enabled">true</setting> 451c451 < <setting name="enabled" control="allocation-profiling-enabled">false</setting> --- > <setting name="enabled" control="allocation-profiling-enabled">true</setting>
そしてプロファイリング開始時にこの設定を使ってプロファイリング開始するようにする
$ jcmd 3857 JFR.start settings=myprofile
これで先ほどと同じ通りにプロファイリングデータのダンプを取得してJMCに読み込ませれば、該当のプロファイリングが有効になってました。
参考:
Java Mission Control + Flight RecorderをGlassFish4で使ってみた - ブログなんだよもん
Running Java Flight Recorder
[http://hirt.se/blog/?p=370Creating Flight Recordings | Marcus Hirt
[http://hirt.se/blog/?p=381Allocation Profiling in Java Mission Control | Marcus Hirt