データの記録
プロファイラの主な目的は、一般的な問題を解決するのに役立つさまざまなソースからのランタイムデータを記録することです。このタスクの主な問題は、実行中のJVMが膨大な量のデータを生成することです。プロファイラが常にすべての種類のデータを記録していた場合、許容できないオーバーヘッドが発生するか、すぐに利用可能なメモリを使い果たしてしまいます。また、特定のユースケースに関連するデータを記録し、無関係なアクティビティを見ないようにしたいことがよくあります。
これが、JProfilerが実際に興味のある情報の記録を制御するための細かいメカニズムを提供する理由です。
スカラー値とテレメトリー
プロファイラの観点から、最も問題の少ないデータ形式はスカラー値です。たとえば、アクティブなスレッドの数やオープンなJDBC接続の数です。JProfilerは通常1秒に1回の固定されたマクロ的な頻度でそのような値をサンプリングし、時間の経過に伴う変化を表示できます。JProfilerでは、そのようなデータを表示するビューはテレメトリー
と呼ばれます。ほとんどのテレメトリーは常に記録されます。なぜなら、測定のオーバーヘッドとメモリ消費が小さいからです。データが長時間記録される場合、古いデータポイントは統合され、メモリ消費が時間とともに線形に増加しないようにします。
また、各クラスのインスタンス数などのパラメータ化されたテレメトリーもあります。この追加の次元により、恒久的な時系列記録は持続不可能になります。JProfilerに選択されたクラスのインスタンス数のテレメトリーを記録するよう指示できますが、すべてのクラスについて記録するわけではありません。
前の例を続けると、JProfilerはすべてのクラスのインスタンス数を表示できますが、時系列情報はありません。これは「すべてのオブジェクト」ビューであり、各クラスをテーブルの行として表示します。ビューの更新頻度は1秒に1回よりも低く、測定が引き起こすオーバーヘッドに応じて自動的に調整される場合があります。すべてのクラスのインスタンス数を決定することは比較的高価であり、ヒープ上のオブジェクトが多いほど時間がかかります。これが「すべてのオブジェクト」が自動的に更新されず、すべてのオブジェクトの新しいダンプを手動で作成する必要がある理由です。
一部の測定は、スレッドが現在いる実行ステータスのような列挙型の値をキャプチャします。この種の測定は、カラー化されたタイムラインとして表示でき、数値テレメトリーよりもはるかに少ないメモリを消費します。スレッドステータスの場合、「スレッド履歴」ビューはJVM内のすべてのスレッドのタイムラインを表示します。数値値を持つテレメトリーと同様に、古い値は統合され、メモリ消費を減らすためにより粗い粒度にされます。
割り当て記録
特定の時間間隔に割り当てられたインスタンス数に興味がある場合、JProfilerはすべての割り当てを追跡する必要があります。「すべてのオブジェクト」ビューとは異なり、JProfilerはヒープ内のすべてのオブジェクトを反復して情報をオンデマンドで取得できますが、単一の割り当てを追跡するには、各オブジェクト割り当てに対して追加のコードを実行する必要があります。これにより、非常に高価な測定が行われ、特に多くのオブジェクトを割り当てる場合、プロファイルされたアプリケーションのランタイム特性、特にパフォーマンスホットスポットを大幅に変更する可能性があります。これが、割り当て記録を明示的に開始および停止する必要がある理由です。
記録が関連付けられたビューは、最初は記録ボタンがある空のページを表示します。同じ記録ボタンはツールバーにもあります。
割り当て記録は、割り当てられたインスタンスの数だけでなく、割り当てスタックトレースも記録します。各割り当て記録のスタックトレースをメモリに保持することは過剰なオーバーヘッドを生むため、JProfilerは記録されたスタックトレースをツリーに累積します。これにより、データをはるかに簡単に解釈できるという利点もあります。ただし、時系列の側面は失われ、データから特定の時間範囲を抽出する方法はありません。
メモリ分析
割り当て記録は、オブジェクトがどこで割り当てられたかを測定することしかできず、オブジェクト間の参照に関する情報はありません。メモリリークの解決など、参照を必要とするメモリ分析は、ヒープウォーカーで行われます。ヒープウォーカーはヒープ全体のスナップショットを撮り、それを分析します。これはJVMを一時停止させる侵襲的な操作であり、長時間かかる可能性があり、大量のメモリを必要とします。
より軽量な操作は、ユースケースを開始する前にヒープ上のすべてのオブジェクトをマークし、後でヒープスナップショットを撮るときに新しく割り当てられたオブジェクトを見つけることができるようにすることです。
JVMには、古いHPROFプロファイリングエージェントにちなんで名付けられたファイルにヒープ全体をダンプするための特別なトリガーがあります。これはプロファイリングインターフェースとは関係がなく、その制約下で動作しません。このため、HPROFヒープダンプはより高速で、リソースを少なく使用します。欠点は、ヒープウォーカーでヒープスナップショットを表示するときにJVMとのライブ接続がないことと、一部の機能が利用できないことです。
メソッドコール記録
メソッドコールがどれくらいの時間かかるかを測定することは、割り当て記録と同様にオプションの記録です。メソッドコールはツリーに累積され、呼び出しグラフなど、さまざまな視点から記録されたデータを表示するビューがあります。このタイプのデータの記録は、JProfilerでは「CPU記録」と呼ばれます。
特定の状況下では、特に複数のスレッドが関与している場合、メソッドコールの時系列を確認することが有用です。これらの特別なケースのために、JProfilerは「コールトレーサー」ビューを提供します。このビューには、より一般的なCPU記録に結び付けられていない別の記録タイプがあります。コールトレーサーは、パフォーマンス問題を解決するのに役立つデータを生成しすぎるため、特定の形式のデバッグのみに使用されます。
コールトレーサーはCPU記録に依存しており、必要に応じて自動的にオンにします。
独自の記録を持つ別の特殊なビューは「複雑性分析」です。これは選択されたメソッドの実行時間のみを測定し、CPU記録を有効にする必要はありません。追加のデータ軸は、スクリプトで計算できるメソッドコールのアルゴリズム的複雑性の数値値です。このようにして、メソッドの実行時間がそのパラメータにどのように依存するかを測定できます。
モニター記録
スレッドが待機またはブロックしている理由を分析するには、対応するイベントを記録する必要があります。そのようなイベントの発生率は大きく異なります。スレッドが頻繁にタスクを調整したり、共通のリソースを共有したりするマルチスレッドプログラムでは、そのようなイベントの数が膨大になる可能性があります。このため、そのような時系列データはデフォルトでは記録されません。
モニター記録をオンにすると、「ロック履歴グラフ」と「モニター履歴」ビューがデータを表示し始めます。
ノイズを排除し、メモリ消費を減らすために、非常に短いイベントは記録されません。ビュー設定でこれらのしきい値を調整することができます。
プローブ記録
プローブは、JVM内のJDBCコールやファイル操作などの高レベルのサブシステムを示します。デフォルトでは、プローブは記録されず、各プローブの記録を個別に切り替えることができます。アプリケーションが何をしているか、プローブがどのように構成されているかによって、一部のプローブは非常に少ないまたはまったくオーバーヘッドを追加しない場合もあれば、かなりの量のデータを生成する場合もあります。
割り当て記録やメソッドコール記録と同様に、プローブデータは累積され、時系列情報はタイムラインやテレメトリーを除いて破棄されます。ただし、ほとんどのプローブには「イベント」ビューもあり、単一のイベントを調査できます。これにより、潜在的に大きなオーバーヘッドが追加され、別の記録アクションがあります。その記録アクションのステータスは永続的であるため、プローブ記録を切り替えると、以前にオンにしていた場合は関連するイベント記録も切り替わります。
JDBCプローブには、JDBC接続リークを記録するための3番目の記録アクションがあります。接続リークを調査しようとしている場合にのみ、接続リークを探すことに関連するオーバーヘッドが発生します。イベント記録アクションと同様に、リーク記録アクションの選択状態は永続的です。
記録プロファイル
多くの状況で、単一のクリックでさまざまな記録を開始または停止したいことがあります。対応するビューをすべて訪れて、記録ボタンを一つずつ切り替えるのは非現実的です。これが、JProfilerに記録プロファイルがある理由です。記録プロファイルは、ツールバーの記録開始ボタンをクリックして作成できます。
記録プロファイルは、原子的にアクティブ化できる特定の記録の組み合わせを定義します。JProfilerは、選択した記録によって引き起こされるオーバーヘッドについて大まかな印象を与えようとし、問題のある組み合わせを避けるようにします。特に、割り当て記録とCPU記録は一緒にうまく機能しません。なぜなら、割り当て記録がCPUデータのタイミングを大幅に歪めるからです。
セッションが実行中のときにいつでも記録プロファイルをアクティブ化できます。記録プロファイルは加算的ではなく、記録プロファイルに含まれていないすべての記録を停止します。記録停止ボタンを使用すると、どのようにアクティブ化されたかに関係なく、すべての記録を停止します。現在アクティブな記録を確認するには、ステータスバーの記録ラベルにマウスをホバーします。
記録プロファイルは、プロファイリングを開始するときに直接アクティブ化することもできます。「セッション開始」ダイアログには、初期記録プロファイルドロップダウンがあります。デフォルトでは、記録プロファイルは選択されていませんが、JVMの起動フェーズからデータが必要な場合は、ここで必要な記録を設定します。
トリガーを使用した記録
特定の条件が発生したときに記録を開始したい場合があります。JProfilerには、アクションのリストを実行するトリガーを定義するための システムがあります。利用可能なトリガーアクションには、アクティブな記録の変更も含まれます。
たとえば、特定のメソッドが実行されたときにのみ記録を開始したい場合があります。その場合、セッション設定ダイアログに移動し、トリガー設定タブをアクティブにして、そのメソッドのメソッドトリガーを定義します。アクション設定では、さまざまな記録アクションを選択できます。
「記録開始」アクションは、パラメータなしでそれらの記録を制御します。通常、記録を停止して再開すると、以前に記録されたデータはすべてクリアされます。「CPUデータ」と「割り当てデータ」の記録では、以前のデータを保持し、複数の間隔にわたって累積を続けるオプションもあります。
メソッドトリガーは、コンテキストメニューの「メソッドトリガーを追加」アクションを使用して、呼び出しツリーで便利に追加できます。同じセッションにすでにメソッドトリガーがある場合は、既存のトリガーにメソッドインターセプションを追加することを選択できます。
デフォルトでは、トリガーはプロファイリングのためにJVMが開始されたときにアクティブです。起動時にトリガーを無効にする方法は2つあります。トリガー設定で個別に無効にするか、セッション開始ダイアログの起動時にトリガーを有効にするチェックボックスをオフにします。ライブセッション中に、メニューからプロファイリング→(有効|無効)
トリガーを選択するか、ステータスバーの
時には、同時にトリガーのグループのアクティベーションを切り替える必要があります。これは、興味のあるトリガーに同じグループIDを割り当て、メニューからプロファイリング→トリガーグループを有効にするを呼び出すことで可能です。
jpcontrollerを使用した記録
JProfilerには、すでにプロファイルされている任意のJVMで記録を制御するためのコマンドライン実行可能ファイルがあります。は、JProfiler
MBeanが公開されていることを要求します。そうでない場合、プロファイルされたJVMに接続できません。これは、プロファイリングエージェントがすでにプロファイリング設定を受け取っている場合にのみ当てはまります。プロファイリング設定がない場合、エージェントは正確に何を記録するかを知りません。
jpcontroller
次のいずれかの条件が適用される必要があります。
- JProfiler GUIでJVMにすでに接続している
-
プロファイルされたJVMが、
-agentpath
VMパラメータを使用して開始され、nowait
およびconfig
パラメータの両方が含まれている。この場合、統合ウィザードでは、すぐに起動モードと起動時に設定を適用オプションに対応します。 -
JVMが
実行可能ファイルでプロファイリングの準備がされ、 jpenable
-offline
パラメータが指定されている。詳細については、の出力を参照してください。 jpenable -help
特に、プロファイルされたJVMがnowait
フラグのみで開始された場合、は機能しません。統合ウィザードでは、JProfiler
GUIで接続時に設定を適用オプションが設定同期ステップでそのようなパラメータを構成します。詳細については、 jpcontroller起動時のプロファイリング設定の設定に関するヘルプトピックを参照してください。
jpcontrollerは、すべての記録とそのパラメータのためのループするマルチレベルメニューを提供します。また、スナップショットを保存することもできます。
プログラムによる記録の開始方法
記録を開始するもう一つの方法は、APIを通じて行うことです。プロファイルされたVMでは、com.jprofiler.api.controller.Controller
クラスを呼び出して、プログラムで記録を開始および停止できます。詳細とコントローラークラスを含むアーティファクトの取得方法については、オフラインプロファイリングに関する章を参照してください。
別のJVMで記録を制御したい場合、でも使用されるプロファイルされたJVMの同じMBeanにアクセスできます。MBeanのプログラムによる使用を設定することはやや複雑で、かなりの手間がかかるため、JProfilerには再利用できる例が付属しています。ファイル jpcontroller
api/samples/mbean/src/MBeanProgrammaticAccessExample.java
を確認してください。これは、別のプロファイルされたJVMで5秒間CPUデータを記録し、スナップショットをディスクに保存します。