JProfiler ヘルプDownload

スレッドプロファイリング


スレッドを誤って使用すると、さまざまな種類の問題が発生する可能性があります。アクティブなスレッドが多すぎるとスレッド飢餓が発生し、スレッドが互いにブロックし合ってアプリケーションの生存性に影響を与えたり、ロックを誤った順序で取得するとデッドロックが発生する可能性があります。さらに、スレッドに関する情報はデバッグ目的で重要です。

JProfilerでは、スレッドプロファイリングが2つのビューセクションに分かれています。「スレッド」セクションはスレッドのライフサイクルとスレッドダンプのキャプチャを扱います。「モニター & ロック」セクションは、複数のスレッドの相互作用を分析するための機能を提供します。

スレッドの検査

スレッド履歴ビューでは、各スレッドがタイムラインの中で色付きの行として表示され、色は記録されたスレッドの状態を示します。スレッドは作成時間、名前、またはスレッドグループでソートされ、名前でフィルタリングすることができます。また、ドラッグ&ドロップでスレッドの順序を自分で再配置することもできます。モニターイベントが記録されている場合、「待機中」または「ブロック中」の状態にあるスレッドの部分にカーソルを合わせると、関連するスタックトレースが表示され、モニター履歴ビューへのリンクが表示されます。

すべてのスレッドの表形式のビューはスレッドモニタービューで利用可能です。スレッドが作成されている間にCPU記録がアクティブである場合、JProfilerは作成スレッドの名前を保存し、テーブルに表示します。下部には、作成スレッドのスタックトレースが表示されます。パフォーマンス上の理由から、JVMから実際のスタックトレースは要求されず、CPU記録からの現在の情報が使用されます。これは、スタックトレースが呼び出しツリー収集のフィルタ設定を満たすクラスのみを表示することを意味します。

プロファイリング設定で推定CPU時間の記録を有効にすると、CPU Time列がテーブルに追加されます。CPU時間は、CPUデータを記録しているときにのみ測定されます。

ほとんどのデバッガーと同様に、JProfilerもスレッドダンプを取得できます。スレッドダンプのスタックトレースは、JVMによって提供される完全なスタックトレースであり、CPU記録に依存しません。異なるスレッドダンプは、2つのスレッドダンプを選択してShow Differenceボタンをクリックすると、差分ビューアで比較できます。また、単一のスレッドダンプから2つのスレッドを選択して、コンテキストメニューからShow Differenceを選択することで比較することも可能です。

スレッドダンプは、「Trigger thread dump」トリガーアクションまたはAPIを介しても取得できます。

ロック状況の分析

すべてのJavaオブジェクトには、2つの同期操作に使用できる関連するモニターがあります。スレッドは、他のスレッドが通知を発行するまでモニターで待機するか、モニターのロックを取得し、他のスレッドがロックの所有権を放棄するまでブロックすることができます。さらに、Javaは、より高度なロック戦略を実装するためのjava.util.concurrent.locksパッケージ内のクラスを提供します。このパッケージ内のロックは、オブジェクトのモニターを使用せず、異なるネイティブ実装を使用します。

JProfilerは、上記の両方のメカニズムに対してロック状況を記録できます。ロック状況では、1つまたは複数のスレッド、モニター、またはjava.util.concurrent.locks.Lockのインスタンス、および一定の時間を要する待機またはブロック操作があります。これらのロック状況は、モニター履歴ビューで表形式で表示され、ロック履歴グラフで視覚的に表示されます。

ロック履歴グラフは、孤立したモニターイベントの期間よりも、関与するすべてのモニターとスレッドの関係全体に焦点を当てています。ロック状況に参加しているスレッドとモニターは青と灰色の長方形として描かれ、デッドロックの一部である場合は赤で描かれます。黒い矢印はモニターの所有権を示し、黄色の矢印は待機中のスレッドから関連するモニターに伸び、破線の赤い矢印はスレッドがモニターを取得しようとして現在ブロックしていることを示します。CPUデータが記録されている場合、ブロックまたは待機中の矢印にカーソルを合わせるとスタックトレースが表示されます。これらのツールチップには、モニター履歴ビューの対応する行に移動するハイパーリンクが含まれています。

表形式のモニター履歴ビューはモニターイベントを表示します。これらには列として表示される期間があり、テーブルをソートすることで最も重要なイベントを見つけることができます。表形式のビューで選択された行に対して、Show in Graphアクションを使用してグラフにジャンプできます。

各モニターイベントには関連するモニターがあります。Monitor Class列には、モニターが使用されているインスタンスのクラス名が表示され、Javaオブジェクトがモニターに関連付けられていない場合は「[raw monitor]」と表示されます。いずれの場合も、モニターには一意のIDがあり、別の列に表示されるため、複数のイベントにわたる同じモニターの使用を関連付けることができます。各モニターイベントには、操作を実行している待機スレッドと、操作をブロックしている所有スレッドがオプションであります。利用可能な場合、それらのスタックトレースはビューの下部に表示されます。

モニターインスタンスについてさらに質問がある場合は、モニター履歴ビューとロック履歴グラフの両方でShow in Heap Walkerアクションを使用すると、ヒープウォーカーへのリンクが提供され、モニターインスタンスが新しいオブジェクトセットとして選択されます。

関心のあるイベントの制限

モニターイベントを分析する際の基本的な問題の1つは、アプリケーションが非常に高い頻度でモニターイベントを生成する可能性があることです。そのため、JProfilerには待機およびブロックイベントのデフォルトのしきい値があり、これを下回るイベントは即座に破棄されます。これらのしきい値はビュー設定で定義されており、より長いイベントに焦点を当てるために増やすことができます。

記録されたイベントには、さらにフィルタを適用することができます。モニター履歴ビューでは、しきい値、イベントタイプ、およびテキストフィルタがビューの上部に提供されています。ロック履歴グラフでは、関心のあるスレッドまたはモニターを選択し、マークされたエンティティを含むロック状況のみを表示することができます。関心のあるイベントはタイムラインで異なる色で表示され、これらのイベントを通過するための二次ナビゲーションバーがあります。現在のイベントが関心のあるイベントでない場合、現在のイベントと次の関心のあるイベントの間にどれだけのイベントがあるかを確認できます。

選択したスレッドまたはモニターが存在するロック状況に加えて、グラフから削除されたロック状況も表示されます。これは、各モニターイベントが、操作が開始されたロック状況と終了したロック状況の2つによって定義されるためです。完全に空のグラフも、JVMにロックがないことを示す有効なロック状況です。

注意が必要なイベントの数を減らすための別の戦略は、ロック状況を累積することです。ロック履歴グラフでは、下部にすべての記録されたイベントを示すタイムラインがあります。これをクリックしてドラッグすると、時間範囲が選択され、含まれるすべてのイベントのデータが上のロックグラフに表示されます。累積グラフでは、各矢印に同じタイプの複数のイベントが含まれることがあります。その場合、ツールチップウィンドウにはイベントの数と含まれるすべてのイベントの合計時間が表示されます。ツールチップウィンドウのドロップダウンリストにはタイムスタンプが表示され、異なるイベント間を切り替えることができます。

デッドロック検出

「現在のロックグラフ」と「現在のモニター」ビューは、JProfiler UIのアクションでトリガーされる「モニターダンプ」で動作します。モニターダンプを使用すると、進行中のイベントを検査できます。これには、決して終了しないイベントであるデッドロックが含まれ、履歴ビューには表示されません。

ブロック操作は通常短命ですが、デッドロックが発生した場合、両方のビューは問題の永続的なビューを表示します。さらに、現在のロックグラフは、デッドロックを引き起こすスレッドとモニターを赤で表示するため、そのような問題をすぐに見つけることができます。

新しいモニターダンプを取得すると、両方のビューのデータが置き換えられます。モニターダンプは、「Trigger monitor dump」トリガーアクションまたはAPIを介してもトリガーできます。

モニター使用統計

より高い視点からブロックおよび待機操作を調査するために、モニター統計ビューはモニター記録データからレポートを計算します。モニターイベントをモニター、スレッド名、またはモニターのクラスでグループ化し、各行の累積カウントと期間を分析できます。