hpjmeterツアー - h50146.ƒ„アー hpjmeterツアーへようこそ!...
TRANSCRIPT
HPjmeterツアー
HPjmeterツアー へ ようこそ!
このサイトは、HPのJava™パフォーマンス解析ツール、
HPjmeterを知っていただくためのサイトです。HPjmeterの豊富な機能の使用法について詳細な手順をご紹介します。
手順の中でスクリーンショットを使用して、この強力なツールの機能をより深くご理解いただけるよう努めました。
HPjmeterツアー の トピック
HPjmeterの要件とプロファイリングの概要
HPjmeterの起動
ファイル統計情報のオープンと参照
メソッド呼び出し回数の解析
メソッド呼び出し回数画面のカスタマイズ
特定のメソッドを呼び出しているメソッドの判定
メソッドのマーク
メトリクスの保存
例
メトリクスの利用
メソッド実行時間の参照と解析
メソッドの検索
例
メトリクスの比較
クラス実行時間の参照
コールグラフツリーの参照
例
例
インライン化候補のメソッドの判定
スレッドのライフタイムの参照
個々のスレッドやスレッドグループの解析
例
円グラフビューの使用
パフォーマンス ボトルネックの検出
ロック コンテンションの検出
作成されたオブジェクトの参照
残ったオブジェクトの参照
作成されたオブジェクトと残ったオブジェクトの数の比較
プロファイル データファイルの比較
ご質問やご意見をお待ちしております。
JavaおよびJavaに関連する商標およびロゴは、Sun Microsystems, Inc.の商標または登録商標です。
結論
HPjmeterの要 件とプロファイリングの概 要
HPjmeterは100%ピュアなJava™アプリケーションなので、Java仮想マシンさえあればこの
ツールを使用することができます。Java 1.1.xをご使用の場合は、Swingもインストールされて
いる必要があります。SwingはJava Foundation ClassesのWebサイトからダウンロードで
きます。Java 1.2.xをご使用の場合は、他に必要なものはありません。
プロファイリングの 概 要
HPjmeterを使用してJavaアプリケーションを分析するには、プロファイルデータを生成するよ
う、Java仮想マシンを適切なオプションで実行する必要があります。次に、JVMの各バージョン固有のオプションについて簡単に説明します。
Java 1.1.x
JVMを-profオプションで実行します。これによってメソッドの包括的(そのメソッドから呼び出し
たメソッドの分を含む)クロック時間とメソッドの呼び出し回数のデータを収集します。このデータはプロセス全体について収集されます。特定のスレッドを対象とするわけではありません。
HP-UX 10.20 および 11.0用 JDK 1.1.8
HP-UX用JDK 1.1.8には、-eprofという、拡張されたプロファイリングオプションがあります。拡
張されたプロファイラでは、-profオプションで収集されるメトリクスに加え、メソッドの包括的クロック時間とメソッドの呼び出し回数についてのコールグラフツリーの情報を収集します。この情報
は、スレッド個々について収集されます。また、HP-UX 11.0のネイティブスレッド バージョンで
は、メソッドの包括的CPU時間の情報も収集されます。
Java 2
Java 1.2では、hprofプロファイリングエージェントを含む試験的なプロファイリング インタフェ
ースが導入されています。HPjmeterは、JavaSoftのSolaris™およびWindows NT向け
JDK 1.2.1-A (Classic VM)およびJDK 1.3.0-C (ClassicまたはHotSpot 2.0 VM)のリファレンスインプリメンテーションと互換性のあるフォーマットのファイルをサポートしています。
HP-UX用Java SDK 1.2.2およびSDK 1.3 beta2のClassic Editionは互換性のあるファイルを生成します。このプロファイラを使用するには、-Xrunhprofオプションで実行します。一点
注意すべきことは、hprofはメソッドの引き数を一覧表示しないということです。そのため、オーバーロードされたメソッドは全て一つのメソッドとして表示されます。
HP-UX 11.0用 Java 2 SDK、HotSpot VM
Java 2プラットフォームのバージョン1.2.2.05向けHP-UX SDK用のHotSpot仮想マシンは、
プロファイリングのための-Xeprofオプションをサポートしています。HotSpotコンパイラは頻繁に呼ばれるメソッドをインライン化してアプリケーションを最適化するため、インライン化されたメソッドは「呼び出し」としてはカウントされません。オブジェクトのコンストラクタの呼び出しもインライン化されるため、作成されたオブジェクトのカウントは信頼できないものになります。正確なメソ
ッド呼び出し回数を取得し、有効なオブジェクトメトリクスを作成させるには、-Xintオプションを使
用してインタープリタモードでVMを起動するか、-Xeprofオプションでinlining=disableを指定します。
JavaおよびJavaに関連する商標およびロゴは、Sun Microsystems, Inc.の商標または登録商標です。
HPjmeterの起 動
HPjmeterは100%ピュアなJava™アプリケーションであるため、ダウンロードしたファイルに含
まれる.jarファイルのJava仮想マシンを起動すればHPjmeterも起動します。
Unixで起動する方法は、Javaのバージョンと使用するシェルによって異なります。
Java 1.1.xをご使 用 の 場 合
Swingのjarファイルが、CLASSPATHの場所に含まれている必要があります。次に、Java 1.1.xで、CシェルとKornシェルでHPjmeterを起動する方法の例を示します。Javaインタープリタがパスの通った場所にあることが前提となります。
Cシェル:
setenv DISPLAY <使用しているディスプレイ>:0.0 setenv SWINGLOC <swingall.jarがインストールされているディレクトリ> setenv HPJMETERLOC <HPjmeter.jarがインストールされているディレクトリ> setenv CLASSPATH $HPJMETERLOC/HPjmeter.jar:$SWINGLOC/swingall.jar java -mx64m HPjmeter
Kornシェル:
export DISPLAY=<使用しているディスプレイ>:0.0 SWINGLOC=<swingall.jarがインストールされているディレクトリ> HPJMETERLOC= <HPjmeter.jarがインストールされているディレクトリ> export CLASSPATH=$HPJMETERLOC/HPjmeter.jar:$SWINGLOC/swingall.jar java -mx64m HPjmeter
Java 1.2.xをご使 用 の 場 合
Cシェル:
setenv DISPLAY <使用しているディスプレイ>:0.0 setenv HPJMETERLOC <HPjmeter.jarがインストールされているディレクトリ> java -mx64m -jar $HPJMETERLOC/HPjmeter.jar
Kornシェル:
export DISPLAY=<使用しているディスプレイ>:0.0 HPJMETERLOC=<HPjmeter.jarがインストールされているディレクトリ> java -mx64m -jar $HPJMETERLOC/HPjmeter.jar
ファイル 統 計 情 報 の オー プンと参 照
HPjmeterが起動したら、[File]メニューをクリックして[Open]を選択するか、ツールバーの
[Open Folder]アイコンをクリックして、プロファイル データファイルをオープンします。すると、次のような通常のオープンダイアログが表示されます。
プロファイル データファイルを作成したディレクトリに移動し、ファイルを選択して[Open]をクリッ
クします。プロファイル データファイルのデフォルト名はjava.prof、java.eprof、java.hprof.txtのいずれかです。
HPjmeterがプロファイル データファイルを解釈し終わると、[File Statistics]画面が、次のように表示されます。ここでは、解析対象のファイルについての一般情報が表示されます。
ファイル統計情報の画面には、使用しているJavaのバージョン、アプリケーションの名前、アプリケーションが実行された時刻とその実行時間、プログラムが終了したときにヒープに残っているオブジェクトの合計サイズ、呼び出されたメソッド数、作成されたスレッドの合計数が表示されます。データファイルを作成したプロファイラによっては、不明になる値もあります。
JavaおよびJavaに関連する商標およびロゴは、Sun Microsystems, Inc.の商標または登録商標です。
メソッド呼 び出し回数の 解析
それぞれのメソッドが呼び出された回数を調べるには、[Metric]メニューをクリックし、[Method Call Count]を選択します。すると、次に示すようなビューが表示されます。
メソッドは呼び出し回数の多い順に表示されます。各メソッドの左側に、メソッドの呼び出し回数が表示されます。デフォルトでは、メソッドの一覧にはそれぞれが属するパッケージ名が含まれています。横方向のバーは、そのメソッドが呼び出された回数の他のメソッドとの比率をグラフ表示したものです。
メソッド呼 び 出 し回 数 画 面 の カスタマイズ
[View]メニューで[Package Names]を選択解除すると、パッケージのフルネーム表示をオフにすることができます。メソッド呼び出しの一覧に引き数を表示させてオーバーライドされたメソッ
ドを識別するには、[View]メニューで[Arguments]をクリックします。
[Package Names]オプションをオフに、[Arguments]オプションを有効にした場合、以下のようなビューになります。これらのビューを使用してどのメソッドが頻繁に呼ばれているかを判断することができるため、パフォーマンスを最適化しようとする際にそのメソッドに照準を合わせることができます。
特 定 の メソッドを呼 び 出 しているメソッドの 判 定
特定のメソッドを呼んでいるメソッドを調べるには、[Method Call Count]ウィンドウでそのメソッドをダブルクリックします。すると、次のようなウィンドウが表示されます。ここで、各メソッドがそのメソッドを何回呼び出しているかを見ることができます。
メソッドの マー ク
後で簡単に探せるようにメソッドにマークを設定するには、メソッドをクリックして選択し[Mark to Find]ボタンを押します。また、メインの[Method Call Count]ウィンドウでメソッドを選択し、ツ
ールバーのチェックマーク アイコンをクリックするか、[Edit]メニューで[Mark to Find]を選択して、メソッドにマークを設定することもできます。これは、ほかのメトリクスでそのメソッドを参照する際に便利な方法です。
メトリクスの 保 存
メトリクスの参照中([Call Graph Tree]を除く)、後で参照したり印刷したりするためにメトリク
スを保存したくなったら、[File]メニューから[Save Metric]を選択します。ファイル名を入力し
て、[Save]を選択します。内容がテキストファイルとして保存されます。
例
上の[Method Call Count]ウィンドウで、Stringクラスの2つのメソッド、charAtとlengthが比
較的頻繁に呼び出されているのがわかります。charAtをダブルクリックして、このメソッドの呼び
出し回数が多い原因となっているメソッドを調べます。次の画面で、StringTokenizerクラスの
nextTokenメソッドが、このメソッドを最も多く呼んでいることがわかります。そこで、
nextTokenメソッドに[Mark to Find]を設定し、他のメトリクスで参照できるようにします。
JavaおよびJavaに関連する商標およびロゴは、Sun Microsystems, Inc.の商標または登録商標です。
メトリクスの利用
メトリクスを使用して、メソッド実行時間の参照、メトリクスの比較、クラス実行時間やコールグラフツリーの参照、インライン化するべきメソッドの判定、スレッドの参照と解析などができます。それぞれのメトリクスについて、次で説明します。
メソッド実 行 時 間 の 参 照 と解 析
各メソッドで使用されている時間を参照することができる、便利なメトリクスです。このメトリクスを
参照するには、[Metric]メニューをクリックし、[Exclusive Method Times (Clock)]を選択します。すると次のような画面が表示されます。
メソッドは、時間の長い順に表示されています。メソッドの左側にある数字は、各メソッドの実行中に経過した時間の合計をミリ秒単位で示したものです。横方向のバーは、その情報をグラフ表示したものです。
[Metric]メニューの[Inclusive Method Times (Clock)]オプションは、そのメソッドと、そのメソッドが呼び出したメソッドで経過した時間の合計をミリ秒単位で示したものです。数値はメソッドの左側に表示されます。
[Metric]メニューの下にある[Inclusive Method Times (CPU)]と[Exclusive Method Times (CPU)]も便利なメトリクスです。このメトリクスは、プロファイラによっては使用できない
ことがあります。このオプションは、そのメソッドで使用されたCPU時間を表示します。メソッド呼び出しの左側にある数字は、おおよその時間をミリ秒で示したものです。これは、概算値として
のみ参照してください。CPU時間とクロック時間を比較して、同期メソッドや同期ステートメントのためにどのメソッドで長い待ち時間が発生しているかを判定することができます。
メソッドの 検 索
前に[Mark to Find]を設定したメソッドが参照中のメトリクスのどこにあるかを確認したい場合
は、[Binoculars With a Lightning Bolt]アイコンをクリックするか、[Edit]メニューから
[Find Immediately]を選択します。または、[Edit]メニューから[Find]を選択して次のようなダイアログを表示し、パッケージ名、クラス名、メソッド名でメソッドを検索できます。これは、一つのクラスやパッケージに関連付けた複数のメソッドを参照する場合に便利な方法です。
例
[Method Call Counts]ウィンドウで、nextTokenメソッドに[Mark to Find]を設定してあり
ます。ここで[Binoculars With a Lightning Bolt]アイコンをクリックするか、[Edit]メニュー
から[Find Immediately]を選択します。このメソッドは、相対的に見るとそれほど多くの時間を消費していないことがわかります。そこで、多くのクロック時間を使っているメソッドを検索しま
す。この例では、2番目のメソッドであるsocketReadが、invokeを除く他のメソッドのほぼ倍の
時間を使用しています。このメソッドに[Mark to Find]を設定して、詳しく調査できるようにします。
メトリクスの 比 較
HPjmeterでは、複数のウィンドウを開いて簡単に比較作業をすることができます。[File]メニュ
ーから[New Window]を選択します。1つのウィンドウで[Exclusive Method Times (Clock)]を、もう一方のウィンドウで[Exclusive Method Times (CPU)]を参照します。2つ
の測定結果を比較するには、[Find]機能を使用します。大きな差があれば、長い待ち時間を消費しているメソッドを見つける手がかりになります。この待ち時間を減らすことができれば、パフォーマンスを改善できます。
あるメソッドを呼び出したメソッドを知りたい場合は、そのメソッドをダブルクリックします。オープ
ンされたウィンドウには、呼び出し回数ではなくクロック時間やCPU時間が表示されます。(注意: これは包括的な測定の場合にのみ表示されます。排他的な場合は表示されません)また、
疑わしいメソッドをマークして、[Call Graph Tree]で参照することもできます。チェックマーク ア
イコンをクリックするか、[Edit]メニューから[Mark to Find]を選択します。
クラス実 行 時 間 の 参 照
[Class Times]メトリクスは、クロック時間とCPU時間で利用できます。このメトリクスを参照す
るには、[Metric]メニューから[Exclusive Class Times (Clock)]か[Exclusive Class Times (CPU)]を選択します。すると、次のようなウィンドウが表示されます。
左側の数字は、特定のクラスのすべてのメソッドで消費した時間の合計です。この時間は排他的で、そのクラス以外のメソッド呼び出し時間は含まれません。あるクラスに含まれるすべてのメソッドを参照するには、そのクラスをダブルクリックします。すると、次のようなウィンドウが表示されます。
そのクラスの中で長い時間を消費しているメソッドがあれば、それを選択し[Mark to Find]をク
リックします。次に[Call Graph Tree]など他のメトリクスでそのメソッドを解析し、そのメソッドで消費されている時間を減らす方法を決定します。
このメトリクスは、そのアプリケーションの1つもしくは少数のクラスで実行時間の大半を費やしていないかを発見するのに有効です。その場合、潜在的ボトルネックとなっているそのクラスのパフォーマンスの改善に重点を置くことができます。
コール グラフツリー の 参 照
[Call Graph Tree]は、クロック時間、CPU時間、メソッド呼び出し回数の参照で使用できま
す。これらは[Metric]メニューの下に表示されます。次の図は、クロック時間に基づいた[Call Graph Tree]です。
これが典型的なコールツリーです。ブランチを展開するには、メソッド名の左側にある丸印をクリックします。呼び出されるメソッドは下に表示され、少し字下げされています。ブランチを折りたたむには、もう一度丸印をクリックします。ウィンドウの下部にそれぞれの色が何を示しているかが説明されています。メソッドの左側に丸印がない場合は、そのメソッドが他のメソッドを呼んでい
ないか、呼び出し回数がしきい値(後述)に達していないので、何も含まれていないことを示します。
例
様々なメソッド実行時間のメトリクスやメソッド呼び出し回数を参照していて、詳しく調査する必要のあるメソッドを見つけたとします。例えば、メソッド
java.net.SocketInputStream.socketReadを呼び出しているメソッドについて詳しく知る必
要があるとします(排他的クロック時間が2番目に高いメソッドです)。前に[Mark to Find]を設
定していますので、[Binoculars with a Lightning Bolt]アイコンをクリックするか、[Edit]メニューから[Find Immediately]を選択します。これによりツリーが展開され、次に示すように、参照したいメソッドが強調表示されます。
メソッドの一番左側にある数字は、直前のメソッドから呼び出されたときの、そのメソッドの包括的時間です。包括的というのは、そのメソッドと、そのメソッドから呼び出されたほかのメソッドで使用した時間を合計したもの、という意味です。パーセンテージは、そのメソッドが消費した時間の中で、指定された呼び出し側メソッドのために消費した時間が占める割合です。仮に、"200 (50%, 4 other callers) someClass.someMethod"と表示されている場合、200が総合
計時間の50%ということなので、このメソッドでの包括的時間の合計は400となります。このメソッドを呼び出した他のメソッドの値も表示されます。このメソッドを呼び出しているほかのメソッドを検索する場合は、そのメソッドをダブルクリックします。他の呼び出しメソッドをシングルクリック
し、[Find]ボタンをクリックします。その呼び出しメソッドは、ツリー内で強調表示されます。
ツリーを調べると、この問題となっているメソッドを呼び出しているメソッドを判定できます。このメ
ソッドで消費している時間を減らすには、2つの選択肢があります。一つは、これを呼んでいるメソッドを調べて、このメソッドの呼び出し回数を減らす方法を考えることです。もう一つは、コードを解析し、より効率のよいアルゴリズムを開発して、このメソッドで使う時間を短くすることです。
この2つのアプローチを組み合わせるのが、このメソッドが消費している時間を減らす最も有効な方法です。
展開するツリーが増えると、ツリーを参照するために必要な空間は大きくなります。ツリーが大き
くなりすぎた場合、2つの方法で小さくすることができます。一つは、メソッドをツリーに含めるた
めに必要な最小値を変更することです。[Tree]アイコンをクリックするか、[Tree]メニューから
[Prune]を選択します。次のようなダイアログボックスが表示されるので、スライダを動かしてカットオフ値を変更します。また、このダイアログでグローバルなデフォルト値を変更できます。
一番上位のメソッド呼び出しが必要ない場合は、ツリーの大きさを縮小する方法はもう一つあります。それは新しいルートを設定することです。メソッドを強調表示させ、[Tree]メニューから
[Set as Root(s)]を選択します。これで、強調表示されたメソッドが新しいルートになり、ツリーが小さく、管理しやすくなります。選択されているメソッドよりも上位にあるメソッドはすべてビュー
から削除されます。もう一度ツリー全体を見たい場合は、[Tree]メニューから[Restore Roots]を選択します。また、[Tree]メニューで[Collapse All]を選択すると、全てのツリーを折りたたむことができます。
例
このメトリクスを使用する便利な方法は、時間や呼び出し回数のメトリクスと併用する、というものです。まず、調査する必要のあるメソッドを見つけます。呼び出し回数の多いものや、クロック
時間がCPU時間に比べてはるかに長いメソッドです。[Mark to Find]を使用して、そのメソッド
を他のメトリクスで見つけやすいようにします。次に[Call Graph Tree]を起動し、メソッドを探します。そのメソッドが何度呼ばれたかを調べたい場合は、そのメソッドよりも上にある、そのメソッドを呼び出しているメソッドを全て調べます。目的はこのメソッドを呼び出すメソッドの数を減らすことです。この方法で、このメソッドを呼び出しているメソッドの大半が見つかります。あるいは、そのメソッドで使っている時間を調べたい場合は、問題になっているメソッドのツリーを展開して、時間の多くを使っているメソッドをがどれかを判定します。これによって、パフォーマンスを上げるために調査するべき、速度低下の原因となっている可能性のある場所を見つけることができます。
インライン化 候 補 の メソッドの 判 定
HPjmeterでは、アプリケーションのパフォーマンスを改善するため、インライン化すべきメソッドを挙げることができます。これは、頻繁に呼ばれているメソッドのうち、比較的単純なコードであ
るものが候補になります。インライン化の候補を参照するには、[Guess]メニューから[Inline Candidates]を選択します。すると、次のようなウィンドウが表示されます。
このメソッドに[Mark to Find]を設定して、[Call Graph Tree]のどこにあるかを見つけられる
ようにします。上の例では、Java標準ライブラリに含まれない一部のメソッドが、インライン化の
候補として挙げられています。[Call Tree]でこのメソッドを探し、インライン化が簡単かどうかを
調べる価値があります。インライン化するメソッドの最初の候補をマークして[Method Call Count]メトリクスで探します。次に、そのメソッドをダブルクリックして、それを呼び出しているメソッドを探します。それが数メソッドしかない場合もあります。その場合、そのメソッドを調べて、候補となっているメソッドを、単独のメソッドではなくインライン化することが可能かどうかを検討します。
注意: プロファイル データファイルを作成したプロファイラのバージョンによっては、各メソッドで
浪費している時間が表示されたりされなかったりします。また、HPjmeterではメソッドのソースコードを見ることはできませんので、これはどのメソッドをインライン化すればいいかの目安にすぎません。プログラマが、インライン化によってパフォーマンスの改善がどの程度、実効があるかを考慮する必要があります。また、インライン化するべきかどうかを判断する際には、コードの可読性と、インライン化に適しているかどうかを考慮する必要もあります。
プロファイル データファイルに適切な情報が含まれていれば、HPjmeterは、アプリケーションのライフタイム内に存在した全てのスレッドについての統計値を表示します。最初にファイルをオープンした際、ファイル統計画面にスレッド数の合計が表示されます。
スレッドの ライフタイム の 参 照
スレッドについての詳細を参照するには、[Metric]メニューから[Thread Histogram]を選択します。すると次のような画面が表示されます。
このビューでは、横方向のバーでスレッドの相対的なライフタイムを示しています。バーの位置が、そのスレッドが、プログラムのライフタイム中いつ存在したかを示します。バーは色分けされていて、どのような状態が、スレッドのライフタイムのどれだけを占めていたかを示しています。この色のついたバーは、アプリケーションを最適化する場合に、どのスレッドを検討するべきか
を判断する際に大変便利です。暖色(赤とオレンジ)は、最適化によってパフォーマンスが改善さ
れる場所を示しています。黄色(I/O)も、ある程度は改善される場所を示します。寒色は、待機中などの状態を示します。
この例では、ほとんどの時間をCPU内で消費しているスレッドがいくつかあることがわかります。
このスレッドについて、それが本当に必要なのか、CPU利用を減少させることが可能かどうかを調べてください。
スレッドをダブルクリックすると、個々のスレッドがどのような状態で時間を使っているかの割合を示す円グラフが表示されます。これは、スレッドが時間をどのように分割して使っているかを知るのに便利です。もう一つの手法は、スレッドヒストグラムに仮想の縦線を引き、ある期間内に、どのスレッドがどれだけ存在していたかを調べる方法です。その縦線と横方向のバーが交差しているスレッドを確認してください。
スレッドヒストグラムを参照する場合は、ライフタイムの短いスレッドを探します。スレッドの作成と破棄は高価な処理なので、短期間に多数のスレッドが作成、破棄されると、パフォーマンスに負の影響が出ます。次の例では、バーの長さでわかるとおり、ライフタイムの短いスレッドが多くなっています。
[Thread Group Histogram]も[Metric]メニューの下にあります。このビューは、個々のスレッドだけではなく、あるアプリケーション内の異なるスレッドグループに対する割合が表示される、ということを除けばスレッドヒストグラムと同じです。ここでも、スレッドグループのいずれかをダブルクリックすると円グラフが表示されます。
個 々 の スレッドや スレッドグル ープの 解 析
個々のスレッドやスレッドグループを解析するには、[Scope]メニューから[Thread]か
[Thread Group]を選択します。これによって、ウィンドウが分割され右側のペインに要約されたスレッドヒストグラム、左側のペインにメトリクス、というように表示されます。
メトリクスを参照するには、右側のペインでスレッドをクリックします。[Metric]メニューに移動
し、参照するメトリクスを選択します。次に、選択したスレッドの[Method Call Count]の例を挙げます。
例
上の例では、String.equalsが6,383,130回、呼び出されていることがわかります。このメソッ
ドについて詳しく知るには、通常どおりに[Mark to Find]を設定し、[Call Graph Tree]ビュー
に切り替えて[Find Immediately]を選択します。この場合、パフォーマンスを上げることがで
きるのはStringの使用を制限することである、ということを判断できます。後で、これは最も頻繁に作成されているオブジェクトであることがわかります。
同様のオプションが[Thread Groups]でも使用できます。アプリケーションが多くのスレッドグループを使用している場合、これはプログラム全体の動作を維持したまま、アプリケーションを小さな部分に分割するのによい方法です。
メトリクスを[Thread]のスコープや[Thread Group]のスコープで参照した場合、右側のペインで別のスレッドをクリックすると、対象のスレッドを変更することができます。これは、どのスレッドがどのタスクを実行しているかを判定するのに便利な方法です。また、修正するべき問題を持つスレッドがどれか、期待した通りにきちんと動作しているスレッドはどれかを判定するのにも役立ちます。
円 グ ラフビュー の 使 用
個々のスレッドやスレッドグループを[Threads Histogram]ウィンドウでダブルクリックすると、スレッドやスレッドグループが時間をどのように配分しているかを示す円グラフが表示されます。例を次に示します。
上の例は、ロックの獲得、CPUの使用、I/Oの実行、スリープ、待ちなどで、スレッドやスレッドグループがどれだけの割合で時間を消費しているかを示しています。特定のスレッドがロックの獲得に多くの時間を使っている場合、同期に関する問題が存在しているため、詳しく調べる必要が
あります。同じように、スリープやI/Oの実行に長い時間を使っているスレッドも調べる必要があります。
JavaおよびJavaに関連する商標およびロゴは、Sun Microsystems, Inc.の商標または登録商標です。
パフォーマンス ボトルネックの検 出
HPjmeterは、アプリケーションでパフォーマンス ボトルネックを検出するのに役立ちます。
ロック コンテンションの 検 出
スレッドが同期メソッドや同期ステートメントのロック取得を長時間待っている場合、Java™アプリケーションのボトルネックの一つとして、ロックコンテンションが高いことが挙げられます。ロック
固有のプロファイルデータがなくても、HPjmeterでどのメソッドにロック コンテンションの問題が
あるかを予測できる場合があります。この機能を使用するには、[Guess]メニューから[Lock Contention]を選択します。すると、次のようなウィンドウが表示されます。
このダイアログは、HPjmeterがロック コンテンションの問題があると予測したパッケージ、クラ
ス、メソッドの名前と、浪費されている時間(ミリ秒単位)を表示します。このウィンドウでは、メソッ
ドに[Mark to Find]を設定して、たとえば[Call Graph Tree]で見つけられるようにできます。
この例では、浪費している時間が2番目に長いメソッドは、CNdTimerクラスのresetTimerメソッドです。これは、呼び出し回数を減らすことができないか、そのメソッドを調査すべきであること
を示しています。[Mark to Find]を設定し、下に示す[Call Graph Tree]でそのメソッドを探します。
このビューでは、どのメソッドがresetTimerメソッドを呼び出しているかを調べることができます。まず、このメソッドの呼び出し回数を減らして、ロック待ちで浪費する時間を短くすることを考えます。次に、もし可能であれば、このメソッドで同期処理を完全に取り除くことができないかどうか検討します。それが可能な場合、時間は浪費されなくなります。
注意: HPjmeterは、実行時間が予期したよりもずっと長いメソッドを目安として、ロックコンテンションの高い領域を検出します。これにはヒューリスティックなアルゴリズムが使われています。
これは問題の可能性に対するヒントにすぎません。このツールが[Guess]メニューの下に配置されており、必ずしも完全に正確ではないということを示していることにご注意ください。
作 成 され た オブジェクトの 参 照
パフォーマンスに関する問題のもう一つの原因は、メモリに関わるものです。HPjmeterで、作成された各種類のオブジェクトの数を参照することができます。ここから、それぞれのオブジェクトが作成された場所についての情報を得ることができます。もし、ある種類のオブジェクトが予想よりもはるかに多く作成されていれば、問題の原因になっているメソッドをピンポイントで特定す
ることができます。作成された各種類別のオブジェクトの総数を参照するには、[Metric]メニュ
ーから[Created Objects (Count)]を選択します。その結果、次のようなウィンドウが表示されます。
上の例では、最も作成頻度の高いオブジェクトはStringオブジェクトです。非常に多くのStringが作成されているため、それがどこで作成されているかを調べて、数を減らすことができないか
を検討する価値があります。そうするには、Stringエントリをダブルクリックします。次のようなダイアログボックスが表示されます。
上の例では、Stringクラスのsubstringメソッドと、StringBufferとIntegerクラスのtoStringで多くのStringが作成されていることがわかります。toStringの呼び出しを減らすのは難しいと
考えられますが、substringの呼び出しについて詳しく調査してみてください。[Mark to Find]を設定し、[Call Graph Tree (Call Count)]を表示してそのメソッドを探します。これを実行すると、次のようになります。
このメソッドは2度呼び出されていますが、ここでは1つだけが表示されています。[Call Graph Tree]でこのメソッドを呼び出しているオブジェクトを見ると、StringTokenizerの使用によって
頻繁に呼び出されていることがわかります。さらに、StringTokenizerメソッドを呼び出している
のは、CSpClassNameのappendメソッドです。つまり、このメソッドを中心に
StringTokenizerの使用を減らすべきである、ということを示しています。StringTokenizerの
使用を減らすと、Stringオブジェクトの作成回数も減ります。同じように、作成回数の多いオブジェクトを調査します。
プロファイルデータによっては、[Metric]メニューで、作成された各種類のオブジェクトの合計サイズをバイト単位で表示できるオプションが使用できる場合があります。このオプションを、メモリを大量に使用している大きなオブジェクトの検出に使用することができます。
残 ったオ ブジェクトの 参 照
参照すべきもう一つの項目は、アプリケーションが終了したときにヒープに残されているオブジェクトです。これは、プログラム中の「メモリリーク」の可能性を示します。このメモリリークは、アプ
リケーションが必要としていないのに参照が残っているオブジェクトです。HPjmeterは、メモリリークによってどの種類のオブジェクトがメモリに堆積しつつあるかを表示することができます。プ
ログラムが終了しても残っているオブジェクトを参照するには、[Metric]メニューから[Residual Objects (Count)]を選択します。すると、次のようなウィンドウが表示されます。
残ったオブジェクトのメトリクスには、配列も含め、全てのオブジェクトが表示されます。横方向のバーは、残されているオブジェクトの数をグラフ表示したものです。
作 成 され た オブジェクトと残 った オブジェクトの 数 の 比 較
ある種類のオブジェクトの数が異常に高いと判断する際に、作成されたオブジェクトと残ったオブ
ジェクトの数を比較すると有効です。まず、[Metric]メニューから[Residual Objects (Count)]を選択します。次に[File]メニューから[New Window]を選択し、表示された新しい
ウィンドウの[Metric]メニューから[Created Objects (Count)]を選択します。[Residual Objects]と[Created Objects]のビューを次に示します。
2つのメトリクスを比較することによって、作成されたtoalloc_smallオブジェクトが全て、プログ
ラムの終了後も残っていることがわかります。また、作成されたStringの約半分が、プログラム終了後も残っていることがわかります。どちらも、メモリリークが疑われます。
また、残ったオブジェクトが何バイトの領域を占めているかを参照するのも有効です。これにより、メモリの消費に最も大きなインパクトを持ったオブジェクトに注目することができます。
プロファイル デー タファイル の 比 較
2つの異なるプロファイル データファイルを生成し比較するのが有効な場合もよくあります。これによって、特定の変更がどの程度パフォーマンスに影響を与えたかがわかります。また、アプリ
ケーションの起動後、ある一定の間(たとえば、5分後から10分後まで)に何が起こっているかを
調べることもできます。どちらの場合も、与えられた条件で2度、アプリケーションを実行してプロ
ファイル データファイルを取得します。2度目の実行で、最初のプロファイル データファイルを上
書きしてしまわないように注意してください。両方のファイルが生成されたら、[File]メニューの
[Open]でどちらかをオープンします。同じように、もう一方をオープンします。次に[File]メニュ
ーから[Compare]を選択します。これで、次のように、2つのファイルを横に並べて比較できます。
この比較で、実行時間、残ったヒープのサイズ、メソッドの数、スレッドの数など、2つのファイルの大きな違いを掴むことができます。個々のファイルを解析するのに使用するメトリクスのほとん
どは、2つのファイルを比較する場合にも使用することができます。例として、2つのファイルを比
較した場合の、[Residual Objects (Count)]メトリクスの結果を次に示します。
プラスの値は、最初のファイルよりも2番目のファイルで多くのオブジェクトが作成されていることを示します。マイナスの値は、その反対です。この値で、変更がどのような影響を及ぼしたかを判断できます。これは、パフォーマンス全体ではなく、長期にわたるパフォーマンスについて知りたい場合に任意の初期化条件について調べるのに有効です。アプリケーションをまず一定時間
実行し、次にそれよりも長い時間実行します。次にこの2つを比較し、2度の実行の間に発生したイベントだけが表示されるようにします。
結 論
HPjmeterツアーをご利用いただき、ありがとうございました。もうHPjmeterの主要な機能につ
いては詳しくなられましたね。この強力なツールをJavaアプリケーションのパフォーマンスの向
上にぜひお役立てください。それでは、コーディングをお楽しみください! ご活躍をお祈りします。
JavaおよびJavaに関連する商標およびロゴは、Sun Microsystems, Inc.の商標または登録商標です。