この章は、Java Flight Recorder の導入部としての役割を果たします。これらのセクションがあります。
実行中の Java プログラムの中では実際に何が起こっているのか疑問に思ったことはありますか。「過去に遡り」、システムで問題が発生する直前に何が起こったのかを分析できたらと思ったことはありますか。極めて詳細なレベルのプロファイリングを、パフォーマンスへの影響なしに行いたいですか。Java Flight Recorder は、これらの目標をすべて達成するために開発されました。
Java Flight Recorder (JFR) は、JVM 自体のコアと緊密に統合するとともに、自身のパフォーマンスオーバーヘッドに非常に敏感になることによって、これらすべてを行います。Java Flight Recorder は、JVM の内部動作とその JVM 内で実行されている Java プログラムについて、豊富な情報を提供します。この情報は、プロファイリングや問題の根本原因分析に使用できます。さらに、Java Flight Recorder は実際の高負荷本番環境でも常時有効にできますが、これはパフォーマンスオーバーヘッドがほとんど発生しないからです。
Java Flight Recorder は、JVM に関する詳細情報を捕捉する一方で、Oracle の Fusion Middleware 製品ファミリにも緊密に統合されているため、システムのフルスタックビューを提供します。高レベルの Java サーブレットやデータベースの実行から、スレッド同期やガベージコレクションに関する細粒度の情報まで、あらゆる情報を手軽に入手できます。
Java Flight Recorder は、JVM の内部に存在する記録エンジンと、Java Mission Control クライアントとで構成されています。エンジンによって生成された記録ファイルは、あとでクライアント経由で分析できます。このドキュメントでは主に最初の部分 (JVM) の構成を扱い、Java Mission Control GUI については軽く言及するにとどめます (第 2 章「クイックスタート手順」を参照)。
JVM の Java Flight Recorder を有効にするには、次の起動オプションを使用します。
-XX:+UnlockCommercialFeatures -XX:+FlightRecorder
これらのオプションの詳細については、次の Java SE ドキュメントを参照してください。http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/java.html
(Solaris、Linux)
http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html
(Windows)
Java Flight Recorder の主な用途を次に示します。
プロファイリング
Java Flight Recorder は継続的に、稼働中のシステムに関するデータを大量に保存します。このプロファイリング情報には、スレッドサンプル (プログラムが時間を費やした箇所を示す)、ロックプロファイル、およびガベージコレクション詳細が含まれます。
ブラックボックス分析
Java Flight Recorder は継続的に情報を循環バッファーに保存します。異常検出時にこの情報にアクセスすれば、その原因がわかります。
サポートやデバッグ
Oracle サポートに連絡する際には、Java Flight Recorder によって収集されたデータが、Java アプリケーションの問題を診断しやすくするうえで不可欠となる可能性があります。
Java Flight Recorder の背後にある基本原則は、取得されるすべてのデータはイベントである、ということです。イベントとは、実行中のアプリケーション内や JVM 内で特定の時間に発生する何かです。イベントは、名前とタイムスタンプを持つほか、オプションでペイロードも持ちます。ペイロードは、次のようにイベントのタイプによって異なります。
ガベージコレクタによって生成される Old コレクションイベントのペイロードは、コレクションの前後のヒープサイズになります。
スレッドがロックによってブロックされたことを知らせるイベントのペイロードは、ロックホルダーのスレッド ID になります。
ほとんどのイベントには、名前とタイムスタンプのほかに、発生元のスレッド、イベントが捕捉された時点でのスタックトレース、およびイベントの期間に関する情報も含まれます。Java Flight Recorder では、タイムスタンプの精度はすべてナノ秒です。
要求可能イベントとは、記録エンジンが特定の頻度でポーリングできるイベントのことです。CPU Load Sample は、要求可能イベントの一例です。記録エンジンにこのイベントのポーリングを行わせる間隔を構成できます。
イベント内でアクセス可能な情報を使用すれば、Java Flight Recorder UI は、プログラムの実行中に何が起こったのかを詳しく構築し直すことができます。
Java Flight Recorder は、自身のオーバーヘッドをできるだけ低く抑えるように設計されています。デフォルト設定を使用する場合、内部テストと顧客フィードバックの両方から、パフォーマンスへの影響は 1% 未満であることがわかっています。一部のアプリケーションでは、この値が格段に低くなる可能性があります。ただし、実行時間の短いアプリケーション (本番環境で実行される種類のアプリケーションではない) では、相対的な起動/準備時間が長くなる可能性があり、パフォーマンスへの影響が 1% を超える可能性があります。
Java Flight Recorder は、実行中のシステムを極めて高い詳細レベルでモニターします。このため、Java Flight Recorder で処理可能なデータが大量に生成されます。Java Flight Recorder はできるだけ早い段階でデータをフィルタリングすることで、低いオーバーヘッドを維持します。これは、次の異なる 2 つの方法で行われます。
実際に捕捉されるイベントのタイプを制限する方法。記録を開始する際にこの情報を制御できます (詳細は第 3 章「フライトレコーダーの起動」を参照)。
特定のしきい値を超える期間を持つイベントのみを記録する方法。ほとんどの場合、非常に短いイベントは役に立たないので、破棄してもかまいません。これにより事実上、Java Flight Recorder で処理する必要のあるデータの量が制限されます。捕捉するデータの量を増やしたい場合は、しきい値を変更できます。
Java Flight Recorder は、発生したイベントをすぐにディスクに書き込むわけではありません。代わりに、データをメモリー内バッファーの階層に格納しておき、それらのバッファーがいっぱいになった時点でデータをディスクに移動します。最初、Java Flight Recorder はイベントデータをスレッドローカルバッファーに書き込むため、どのイベントについてもスレッド間の同期を取る必要がなく、したがってスループットが大幅に向上します。スレッドローカルバッファーがいっぱいになると、グローバルバッファーにデータが転送されます。これが起こると、スレッド間の同期が必要になりますが、いっぱいになる速度はスレッドローカルバッファーごとに異なるため、ロックが競合することはめったにありません。最終的にはグローバルバッファーも使い果たされ、バッファーの内容がディスクに書き込まれます。ディスク書き込み操作はコストが高いので、記録対象としてアクティブ化するイベントデータを注意深く選択することで、その操作を最小限に抑えるよう努力すべきです。ディスクファイルへの書き込み時には、独自のバイナリ形式のファイルが生成されますが、この形式は極めてコンパクトであり、しかもアプリケーションから効率的に読み書きできます。
ディスクへのデータ書き込みを一切行わないように Java Flight Recorder を構成できます。このモードでは、グローバルバッファーは循環バッファーとして機能し、バッファーがいっぱいになった時点でもっとも古いデータが破棄されます。この非常にオーバーヘッドの低い操作モードでも、問題の根本原因分析に必要となる重要なデータはすべて収集されます。グローバルバッファーでは最新のデータが常に使用可能となっているため、操作や監視システムによって問題が検出されるたびに、オンデマンドでそれをディスクに書き込むことができます。ただし、このモードで使用可能なのは最後の数分間のデータだけなので、それには最新のイベントしか含まれていません。長期にわたる操作の全履歴を取得する必要がある場合には、イベントが定期的にディスクに書き込まれるデフォルトモードを使用してください。