いまさらだけど、Java Flight Recordeってなに?
Java Flight Recorde(以下、JFR)とは、一言で言うと、Javaのプロファイラーである。
Java SE Advancedに含まれているモジュールで、本番環境で使用するには商用ライセンスが必要(有償)になるが、開発時は無償で利用できる。
JFRは、Java7からJava SE の実行環境に内蔵されていて、
Java実行環境にすでに収集されているデータを効率よく記録してくれる(らしい)!
また、最新のJava9にも含まれる予定になっている。
JFR以外の有名なJavaプロファイラーは、
jvmmonitor 、JProfiler、JProbe、少し前だと、EclipseのTPTP(Test & Performance Tools Platform)とかあるけど、
有償だったり、開発停止して使えなくなっていたり…。
JFRはどんな時に使うのか。何ができるのか。
JFRは、アプリケーションをずっと動かしていると、急にマシンが落ちる!とか、このアプリケーション、レスポンスが悪い!とか、メモリリークの調査が必要であったり、アプリケーションの性能向上が必要である場合に使うツールである。
JFRの機能としては、下記に挙げるものがある。
-
プロファイリング
JFRは継続的に、稼働中のシステムに関するデータを大量に保存する。
このプロファイリング情報には、下記情報などが含まれる。 -
Javaアプリケーションの情報:例外、スレッド、ファイルI/O、ネットワークI/Oなど
-
JavaVMの情報:メモリの割り当て、クラスのロード、JIT、GC、メソッドのサンプリング
-
OSの情報:メモリやCPUの利用情報
-
ブラックボックス分析
JFRは継続的に情報を循環バッファーに保存するため、異常検出時にこの情報にアクセスすると、その原因が分かる。
JFRの使い方
Javaコマンドのオプションで使う
JavaコマンドからJFRを使うには、以下のオプションを指定する。
- 「-XX:+UnlockCommercialFeatures」:商用機能のアンロック
- 「-XX:+FlightRecorder」 :JFRの有効化
- 「-XX:StartFlightRecording」 :JFRの記録を開始する
MyAppアプリケーションを実行して、すぐに60秒間の記録を開始し、それをrecording.jfrという名前のファイルに保存する方法
$ java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=duration=60s,filename=/tmp/recording.jfr MyApp
「-XX:StartFlightRecording」のパラメタは下記参照。
https://docs.oracle.com/cd/E22646_01/doc.40/b61441/optionxx.htm#BABIEFBA
jcmdコマンドで使う
jcmdコマンドは、実行中のJavaプロセスのプロファイリングができるコマンドである。
jcmdコマンドから、JFRを使うには、
Javaアプリケーション起動時に「-XX:+UnlockCommercialFeatures」「-XX:+FlightRecorder」オプションが指定されてる必要がある。
プロセス識別子が5368の実行中Javaプロセスで60秒間の記録を開始し、それをrecording.jfrという名前のファイルに保存する方法
$ jcmd 5368 JFR.start duration=60s filename=/tmp/recording.jfr
Java9で変わるところ!
Java9でJFRのUIが大幅に変わって、より使いやすくなるらしい。
JFR APIがサポートされて、レコーダのコントロール、カスタムイベントの生成ができるようになる。
まとめ
アプリケーションの性能は作り方によって大きく左右されるし、性能劣化の要因の多くは、作り方(作り手)の問題だと思う。
プロファイリングツールを活用し、ボトルネックをうまく見つけ出して修正することができれば、
アプリケーションの性能を劇的に向上させることができる!
より良いモノを開発するために、プロファイリングツールを有効活用してみよう。
JFRは、開発時は無償で利用できます!