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












































