プロジェクト

全般

プロフィール

JDK Flight Recorder

JavaVMの実行時の情報を取得するツールで、本番環境でも適用できるよう計測のオーバーヘッドを少なくするように設計されています。
本記事は、OpenJDK 11以降のFlight Recorderについて記載します。

ツールの操作

レコーディングの種類

  • 連続レコーディング
    • 結果を取得するには明示的にダンプ操作が必要
  • 時間限定レコーディング
    • 指定した時間だけレコーディング
    • Mission Controlからレコーディング開始した場合、自動でMission Controlにダウンロードされる

レコーディングの制御

Flight Recorderのレコーディング制御には次の方法があります。

  • アプリケーション起動時にレコーディングの設定を指定し開始
  • アプリケーション内からAPIでレコーディングを制御
  • jcmdで実行中のJVMにレコーディング制御
  • MBeanインタフェースで実行中のJVMにレコーディング制御

アプリケーション起動時にレコーディングを指定する

アプリケーションを起動する際のJVMオプションでレコーディングを開始します。

-XX:StartFlightRecording

デフォルトの設定でレコーディング開始します。デフォルトは連続レコーディングとなります。

設定を細かく指定することも可能です。次は時間限定レコーディングをprofile設定で開始する例です。

-XX:StartFlightRecording=delay=20s,duration=60s,name=MyRecording,filename=C:\TEMP\myrecording.jfr,settings=profile
  • 起動後にdelay=20sで指定した20秒後からレコーディングを開始します。
  • duration=60sで指定した60秒間の時間限定レコーディングを行います。
    duration指定がないと連続レコーディングを行います。
  • name=MyRecordingでJava Flight Recorderの識別子を指定します。
  • filename=C:\TEMP\myrecording.jfrでレコード結果を記録するファイルを指定します。
  • settings=profileで設定種類(設定ファイル)を指定します。Java SEのデフォルトの設定ファイルは<JREディレクトリ>\lib\jfr\にあります(default.jfc、profile.jfc)。

途中でダンプさせたいときは、Java Mission Controlを接続してダンプ操作をするか、コマンドjcmdでダンプ操作をします。

jcmdからレコーディング制御

jcmd <PID> JFR.start で実行中のJVMにJFRのレコーディング開始を指定します。
jcmd <PID> JFR.check で実行中のJVMのJFR情報を表示します。
jcmd <PID> JFR.dump で実行中のJVMのJFR情報をファイル出力します。

PIDの参照

PIDは、そのユーザー環境で実行されているJVMのIDで、jcmdを実行すると一覧表示されます。

D:\work>jcmd
11520 main.WeatherApplication
260 jdk.jcmd/sun.tools.jcmd.JCmd
18380 JMC
JFR情報の表示
D:\work> jcmd 11520 JFR.check
11520:
Recording 1: name=1 maxsize=250.0MB (running)
JFRのレコーディング開始
D:\work> jcmd 11520 JFR.start

オプションを指定して開始する例

D:\work> jcmd 11520 JFR.start name=MyRecording settings=profile
 delay=20s duration=2m filename=C:\TEMP\myrecording.jfr
JFR情報をファイル出力
D:\work> jcmd 11520 JFR.dump 
11520:
Dumped recording, 2.5 MB written to:

D:\work\hotspot-pid-11520-2022_11_06_10_48_37.jfr

filenameを指定しないとデフォルトのファイル名でJFR情報をファイルに出力します。

オプションを指定してファイル生成

jcmd 11520 JFR.dump name=MyRecording filename=C:\TEMP\dump.jfr

リモートから監視

リモートから監視する場合、MBeanインタフェース(JMX)で接続することが可能です。

com.sun.management.jmxremote関連のフラグを指定して監視対象のJVMを起動します。

認証なし、暗号化なしの接続をポート7091実施
-Dcom.sun.management.jmxremote.port=7091
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

メモ

  • -Dcom.sun.management.jmxremote=true は指定不要

現在のJava SEプラットフォームでは、このシステム・プロパティの設定は必要ありません。どのアプリケーションでも、現在のJava SEプラットフォームで起動したものであればAttach APIがサポートされ、ローカル・モニタリングと管理が必要な場合は自動的に使用可能になります。

(Java SEドキュメント 「モニタリングおよび管理ガイド」2章より)

  • -Dcom.sun.management.jmxremote.rmi.port=7091 (一般的にはcom.sun.management.jmxremote.portと同じ値)を指定しないと
    JMXaアダプタはランダムにポート番号を割当てるので、ファイアウォール構成が困難になります。
認証あり

認証ありにするには、TLSを有効にし(平文でパスワードが流れないために)、ユーザー名とパスワードを定義します。

T.B.D.

レコーディングの生成

Mission Controlから

  • JVMブラウザ上で対象JVMを選び
  • そのJVMのFlight Recorderノードをダブルクリックし、ウィザードに従う
  • レコーディング中の場合はFlight Recorderノードの下にリストされるので、ダブルクリックまたはエディター領域にドラッグ&ドロップ

Flight Recorderの設定

レコーディングの設定

オプション名 デフォルト値 概要
name 1 レコーディングの識別子を指定
settings default 記録する項目の定義、負荷の少ないdefault、やや負荷の多いprofileが規定で提供、ユーザー定義可能
delay 0 JVM起動後からレコーディング開始するまでの待機時間(≧1s), 単位にs(秒), m(分), h(時間), d(日)を使用可
duration 0 レコーディング実施時間、単位は同上
disk true レコーディング中にディスクにデータを書き込むか否かを指定
maxage 0 ディスク上にレコーディングする最大日数を指定、単位にs(秒), m(分), h(時間), d(日)を使用可
maxsize 0 ディスクの最大サイズ
flush-interval
dumponexit false JVMシャットダウン時にレコーディングをダンプするか否かを指定
filename レコーディング停止時に書き込むファイルパス
path-to-gc-roots false レコーディングの最後にGCルートへのパスを収集するか否かを指定

settings

どのような項目を監視・収集するかを定義するプロファイルを指定します。OpenJDKでは、デフォルトで次の2つのプロファイルが用意されています。

  • default
  • profile

これらは、OpenJDKディレクトリ/lib/jfr/ の下に拡張子.jfcで定義ファイルが置かれています。

Flight Recorderのリリースとライセンス

Flight Recorderは、Java SE 7u40からOracle JDKに同梱されています。当初は商用機能として、有償の契約を結んだ場合に利用できました。
JDK 11から、OpenJDKに取り込まれるようになり、OpenJDKのライセンスによって利用できるようになりました。

JDK Mission Control

JDK Mission Control(以下、JMCと呼ぶ)は、稼働しているJavaVM(アプリケーション)の性能解析を行うツールです。稼働中のJavaVMからJMXで取得するメトリクスデータやJavaVMからダンプされたメトリクスデータを可視化し分析するツールです。
メトリクスデータには、Java Flight Recorderが生成するデータも含みます。

JMCの入手とインストール

JMCは、OpenJDKディストリビューターがバイナリを配布しています。

Oracle JMC

Linux、macOS ARM64、macOS Intel、Windowsの各OS用のバイナリが提供されています。
2022年11月6日現在、JMC 8.2.1のバイナリが提供されています。

Windowsでのインストールと起動

Windowsで使用する場合、Windows用のバイナリ jmc-8.2.1_windows-x64.zip をダウンロードし、任意のディレクトリに展開します。
例: C:\Program Files\Java\JDK Mission Control 8.2.1

展開した中に、jmc.exe があるのでこれを実行します。

JMC 8 は、JDK 11以降で実行可能なJavaアプリケーションとなっています。実行するマシンに複数のJDKバージョンが存在する場合、JDK 11以降でJMCが実行されるように設定が必要となる場合があります。この場合、JMCのディレクトリにあるjmc.iniにJMCを実行するJDKのパスを追記します。

  --launcher.appendVmargs
+ -vm
+ C:\Program Files\Java\jdk-17\bin
  -vmargs

JavaVMへの接続

JMCを稼働中のJavaVMに接続するには、次の場合があります。

  • ローカルのマシンで稼働するJavaVMへ接続
  • リモートマシンで稼働するJavaVMへ接続

ローカルのマシンで稼働するJavaVMは、JMCを実行しているユーザー環境で実行されたものが対象となります。ローカルのマシンで稼働するJavaVMに接続する際は、JavaVMに特別な設定は不要です。一方、リモートマシンで稼働するJavaVMに接続する際は、JavaVMにリモートからJMXインタフェースで接続できるよう設定をする必要があります。

ローカルマシンのJavaVM

ローカルマシンで稼働するJavaVMは次の画面の左側(JVMブラウザタブ)に表示されます。

リモートマシンのJavaVM

リモートマシンのJavaVMや、ローカルマシンでも別ユーザー環境で実行されたものはネットワーク接続で利用します。ネットワーク接続の場合は、さきにJavaVMをネットワーク接続対応可能に設定してからJMCで接続します。

JMCからリモートの接続を設定

  • [ファイル]メニュー > [接続] > [新規接続の作成] > [次へ]とクリック

  • 接続先のリモートマシン、ポート番号、作成する接続名を入力
  • ユーザー/パスワードは、認証ありの場合に入力

設定が正しいか接続確認が可能です。リモート接続の設定がされたJavaVMをリモートマシンで稼働してから、[接続のテスト]をクリックします。

JavaVMのメトリクスの取得と表示

JMX(Java Management Extensions)

JMCの左側ペイン JVMブラウザ 上で監視したいJavaVMをドリルダウンし、[MBeanサーバー]を選択します。

右側に、JavaVMから取得した、CPU、メモリの使用状況が表示されます。右側ペインではタブを切り替えてJMXのいろいろな監視・操作機能を使用できます。

Flight Recorder(稼働中のJavaVMからファイル取得)

JMCの左側ペイン JVMブラウザ上で解析したいJavaVMをドリルダウンし、[フライト・レコーダ] > [<レコーディング名>]をダブルクリックします。

稼働中のJavaVMで記録されているFlight Recorderのレコーディングデータの時間範囲を選択、および指定します。
指定したデータは、宛先ファイルに指定したファイルに保存されます。

Flight Recorderのデータを取得すると右側に各種状況を表示できるようになります。

Flight Recorder(ダンプ済みのファイルを開く)

[ファイル]メニュー > [ファイルを開く]で、Flight Recorderのレコーディングファイルを読み込みます。

参考資料


約2年前に更新