この章の構成は、次のとおりです。
この項で説明するコマンド行ユーティリティのほとんどは、JDKに含まれているか、オペレーティング・システムのネイティブなツールやユーティリティです。
JDKコマンド行ユーティリティはJDKのダウンロードに含まれていますが、Java Runtime Environment (JRE)にデプロイされたアプリケーションの問題の診断やモニターのためにそれらを使用できるかどうかを検討するのは重要なことです。
一般に、診断ツールやオプションは、様々なメカニズムを使用して報告対象の情報を取得します。それらのメカニズムは仮想マシン(VM)実装、オペレーティング・システムおよびリリースに固有のものです。通常、ツールの一部のみが、特定の時点で特定の問題に適用可能です。「-XX
」という接頭辞が付いたコマンド行オプションは、Java HotSpot VMに固有のものです。「Java HotSpot VMコマンド行オプション」を参照してください。
注意:
-XX
オプションはJava APIの一部ではなく、リリースごとに変わる可能性があります。
これらのツールおよびオプションは、トラブルシューティングの対象となっている問題のタイプに応じて、いくつかのカテゴリに分けられます。場合によっては、1つ以上のカテゴリに分けられるツールやオプションもあります。
ポストモーテム診断 これらのツールおよびオプションを使用すれば、アプリケーションがクラッシュした後に問題を診断できます。「ポストモーテム診断ツール」を参照してください。
ハングアップ・プロセス これらのツールを使用して、ハング・アップまたはデッドロックしたプロセスを調査できます。「ハングアップ・プロセス・ツール」を参照してください。
モニタリング これらのツールを使用して、実行中のアプリケーションをモニターできます。「モニタリング・ツール」を参照してください。
その他 これらのツールやオプションを使用すれば、その他の問題を診断しやすくなります。「その他のツール、オプション、変数、およびプロパティ」を参照してください。
注意:
この項で説明するコマンド行ユーティリティのいくつかは、試験的なものです。jstack
、jinfo
、およびjmap
ユーティリティが、試験的なユーティリティの例です。以前のjstack
、jinfo
およびjmap
ユーティリティのかわりに最新の診断ツールjcmd
の使用をお薦めします。
Java Mission Control (JMC)は、HotSpot JVM用の新しいJDKプロファイリングおよび診断ツール・プラットフォームです。
基本的なモニタリングと管理、および本番稼働時のプロファイリングと診断を行う高性能なツール・スイートです。Java Mission Controlは、プロファイリング・ツールにつきもののパフォーマンス・オーバーヘッドの問題を最小限に抑えます。このツールはJVMに組み込まれた商用機能であり、実行時に使用できます。
Java Flight Recorder (JFR)は商用機能です。開発者のデスクトップおよびラップトップ上では無償で、また評価目的であればテスト環境、開発環境および本番環境で使用できます。ただし、JFRを本番サーバーで有効にする場合は、商用ライセンスが必要です。それ以外の目的でJMC UIをJDK上で使用する場合、商用ライセンスは必要ありません。
Java Mission Control (JMC)は、Java管理コンソール(JMX)とJava Flight Recorder (JFR)の他、ツールからダウンロード可能ないくつかのプラグインで構成されます。JMXはJavaアプリケーションのモニタリングおよび管理用ツールで、JFRはプロファイリング・ツールです。Java Mission Controlは、Eclipse IDE用のプラグインのセットとしても使用可能です。
次のトピックでは、Java Mission Controlでトラブルシューティングを行う方法を説明します。
Java Flight Recorder (JFR)は商用機能です。開発者のデスクトップおよびラップトップ上では無償で、また評価目的であればテスト環境、開発環境および本番環境で使用できます。
ただし、JFRを本番サーバーで有効にする場合は、商用ライセンスが必要です。それ以外の目的でJMC UIをJDK上で使用する場合、商用ライセンスは必要ありません。
JFRの商用機能と入手方法の詳細は、製品マニュアルを参照してください。
JFRの商用ライセンスの詳細は、ライセンス契約を参照してください。
Javaフライト・レコーダは、JavaランタイムおよびJavaランタイムで実行されているJavaアプリケーションの詳細情報を記録します。記録プロセスによるオーバーヘッドはほとんど発生しません。データは、イベントと呼ばれるタイム・スタンプ付きのデータ・ポイントとして記録されます。一般的なイベントには、ロックを待機中のスレッド、ガベージ・コレクション、定期的なCPU使用率データなどがあります。
フライト記録を作成する場合は、保存するイベントを選択します。これは記録テンプレートと呼ばれています。一部のテンプレートは、ごく基本的なイベントのみを保存し、パフォーマンスにほとんど影響を与えません。他のテンプレートは、いくらかのパフォーマンス・オーバーヘッドが発生し、追加情報を得るためにGCをトリガーする場合もあります。通常、オーバーヘッドが数パーセントを超えることはほとんどありません。
フライト記録は、パフォーマンスの問題からメモリー・リーク、重いロック競合まで、広範囲の問題のデバッグに使用できます。
次のトピックでは、Javaフライト記録を作成する記録の種類について説明します。
連続記録とプロファイリング記録の2種類のフライト記録があります。
連続記録: 連続記録は、常時オンの記録で、たとえば、最近6時間のデータを保存します。アプリケーションで問題が発生した場合は、たとえば、最後の1時間のデータをダンプし、問題発生時に何が起こったかを調べることができます。
連続記録のデフォルト設定は、低いオーバーヘッドで記録プロファイルを使用することです。このプロファイルは、ヒープの統計や割当てプロファイリングを取得しませんが、役立つデータを大量に収集します。
連続記録は、常に実行されていることが重要であり、あまり発生しない問題をデバッグする際に便利です。記録は、jcmdまたはJMCのいずれかを使用して手動でダンプできます。また、特定の条件が満たされたときにフライト記録をダンプするためにJMCにトリガーを設定することもできます。
プロファイリング記録: プロファイリング記録は、オンになると、一定時間実行した後、停止する記録です。通常、プロファイリング記録では、より多くのイベントが有効であり、パフォーマンスへの影響がいくらか大きくなる場合があります。オンにするイベントは、プロファイリング記録の使用に応じて変更できます。
プロファイリング記録の一般的なユース・ケースは次のとおりです。
最もよく実行されるメソッドおよび最も多くのオブジェクトが作成される場所のプロファイルを記録する。
メモリー・リーク発生の指標となる、ヒープ使用量の増加を示しているクラスを探す。
同期に起因するボトルネックおよび多数のこのようなユース・ケースを探す。
プロファイリング記録は、特定の問題のトラブルシューティングをしていない場合にも、多くの情報を提供します。プロファイリング記録では、アプリケーションの全体像を見て、ボトルネックまたは改善の必要な領域を見つけることができます。
注意:
通常のオーバーヘッドは2%程度であるので、パフォーマンスまたはレイテンシに対して非常に慎重である場合を除き、プロファイリング記録は本番環境で実行できます(これはJFRの主要ユース・ケースの1つです)。
次の項では、フライト記録を作成する3つの方法について説明します。
フライト記録を簡単に管理するには、Java Mission Control (JMC)を使用します。
開始するには、図2-1に示すように左端のフレームのJVMブラウザで自分のサーバーを見つけます。
デフォルトでは、ローカルで実行中のすべてのJVM一覧が表示されます。リモートJVM (JMCを実行しているユーザーと同じ有効ユーザーで実行)はリモートJMXエージェントを使用するように設定する必要があります。次に、新しいJVM接続ボタンをクリックし、ネットワークの詳細を入力します。
JDK 8u40より前のリリースでは、-XX:+UnlockCommercialFeatures -XX:FlightRecorder
フラグを指定してJVMが起動されている必要がありました。
JDK 8u40リリースからは、Javaフライト・レコーダを実行時に有効にすることができます。
Java Mission Controlを使用してフライト記録を作成する3つの方法は次のとおりです。
コマンド行で起動フラグを使用して、プロファイリング記録の作成、連続記録、診断コマンドの使用を行います。
JFRフラグの詳細な説明は、Java Platform, Standard Editionツール・リファレンスの高度なランタイム・オプションに関する項を参照してください。
コマンド行で起動フラグを使用してフライト記録を作成する3つの方法は次のとおりです。
条件が満たされた場合にフライト記録を自動的に開始またはダンプするようにJava Mission Controlを設定できます。これはJMXコンソールから実行します。JMXコンソールを起動するには、JVMブラウザでアプリケーションを見つけてそれを右クリックし、JMXブラウザの起動を選択します。
図2-6に示すように、画面の下部にある「トリガー」タブを選択します。
アプリケーション内の任意のMBean
にトリガーを作成することがきます。高いCPU使用率、デッドロック・スレッド、過剰なライブ・セットなどのいくかの一般的な条件のためのデフォルト・トリガーが設定されています。「追加」を選択して、アプリケーション内の任意のMBean
(アプリケーションに固有のものを含む)を選択します。トリガーを選択するとき、満たす必要のある条件も選択できます。詳細は、右上の疑問符をクリックして組込みのヘルプを参照してください。
複数のトリガーを実行するには、トリガーの横のボックスをクリックします。
条件を選択したら、「アクション」タブをクリックします。次に、条件が満たされたときに実行する処理を選択します。最後に、図2-7に示すように、連続記録のダンプまたは期間限定のフライト記録の開始のいずれかを選択します。
フライト記録を検査するためのサンプルJFRの取得方法、およびフライト記録を分析するためのJava Mission Controlの様々なタブについての説明。
次の項で説明します。
フライト記録を作成して、Mission Controlでそれを開くことができます。
フライト記録を作成した後、Mission Controlでそれを開くことができます。フライト記録を検査するための簡単な方法:
範囲ナビゲータを使用して、フライト記録を検査します。
各タブの上部のビューに、範囲ナビゲータがあります。
図2-8の縦棒は、記録内のイベントを表します。棒の高さが高いほど、より多くのイベントがその時点で発生しています。選択された時間の端をドラッグして、記録のズーム・インまたはズーム・アウトができます。範囲ナビゲータをダブルクリックすると、ズーム・アウトして記録全体が表示されます。すべてのサブタブに同じズーム・レベルを適用するには、「選択の同期」チェック・ボックスをクリックします。
詳細は、組込みヘルプの範囲ナビゲータの使用に関する項を参照してください。イベントの名前は、タブの名前どおりです。
「全般」タブのフライト記録を検査します。
「全般」タブには、アプリケーション全般について説明するいくつかのサブタブが含まれています。図2-9に示すように、最初のサブタブは「概要」で、ここには最大ヒープ使用量、合計CPU使用率およびGC一時休止時間などの基本情報が表示されます。
また、CPU使用率の経時的推移、アプリケーションでの使用状況とマシンでの合計を調べます。このタブは、アプリケーションで直接に問題が発生したときに調べるための便利なタブです。たとえば、100%近くまで急上昇しているCPU使用率、低すぎるCPU使用率、またはガベージ・コレクションの一時休止などに注意してください。
注意: ヒープ統計を指定して開始されたプロファイリング記録は、記録の開始時と終了時に、他のコレクションよりも長くかかる可能性がある、2つのOldコレクションを取得します。
また、「JVM情報」サブタブには、JVM情報が表示されます。起動パラメータのサブタブの「システム・プロパティ」には、設定されたすべてのシステム・プロパティが表示され、「記録」には、オンにされたイベントなど、特定の記録に関する情報が表示されます。すべてのタブおよびサブタブについて組込みの詳細を参照するには、疑問符をクリックしてください。
「メモリー」タブのフライト記録を検査します。
「メモリー」タブには、ガベージ・コレクション、割当てパターンおよびオブジェクト統計に関する情報が含まれています。このタブは、メモリー・リークのデバッグおよびGCのチューニングのために特に役立ちます。
「概要」タブには、メモリー使用量に関する一般情報およびガベージ・コレクションに関する統計情報が表示されます。注意: 「概要」タブのグラフでは、目盛の最大値がマシンで使用可能な物理メモリーです。そのため、Javaヒープは、下部のわずかな部分のみを取る場合があります。
「メモリー」タブの3つのサブタブは次のとおりです。
「ガベージ・コレクション」タブ: 「ガベージ・コレクション」タブには、メモリー使用量の経時的推移およびすべてのガベージ・コレクションに関する情報が表示されます。
図2-10に示すように、ヒープ使用量のスパイク状のパターンはまったく正常です。ほとんどのアプリケーションでは、一時オブジェクトが絶えず割り当てられています。条件が満たされると、ガベージ・コレクション(GC)がトリガーされ、使用されなくなったすべてのオブジェクトが削除されます。したがって、ヒープ使用量は、GCがトリガーされるまで絶え間なく増加した後、急激に減少します。
JavaのほとんどのGCには、何らかの小規模なガベージ・コレクションがあります。Old GCではJavaヒープ全体が対象となり、他のGCではヒープの一部を調べる場合があります。Oldコレクション後のヒープ使用量は、アプリケーションで使用されているメモリーであり、ライブ・セットと呼ばれています。
ヒープ統計を有効にして生成されるフライト記録は、Old GCで開始および終了します。GCの一覧からそのOld GCを選択し、「全般」タブを選択して「GC理由」を参照すると、ヒープ検査によるGCの開始であることがわかります。通常、これらのGCは、他のGCよりも少し時間がかかります。
メモリー・リークに対処するための最適な方法としては、最初と最後のOld GCでの「GC後のヒープ」の値を確認してください。この値が経時的に増加している場合は、メモリー・リークの可能性があります。
「GC回数」タブには、GCの実行にかかった時間とGCのためにアプリケーションが完全に一時休止する時間に関する情報があります。「GC構成」タブには、GCの構成に関する情報があります。これらのタブの詳細は、右上の疑問符をクリックして組込みのヘルプを参照してください。
「割当て」タブ: 図2-11では、行われたすべてのメモリー割当ての選択を示しています。Javaの小さなオブジェクトは、TLAB (Thread Local Area Buffer)に割り当てられます。TLABは、新しいオブジェクトが割り当てられている小さなメモリー領域です。TLABが一杯になると、スレッドが新しいものを取得します。すべてのメモリー割当てをログすると、オーバーヘッドが生じるので、新しいTLABをトリガーしたすべての割当てがログされます。大きいオブジェクトは、TLAB外に割り当てられ、これらもログされます。
各クラスのメモリー割当てを推定するには、「新しいTLABの割当て」タブ、「割当て」タブの順に選択します。これらの割当ては、新しいTLABをトリガーするために起こるオブジェクトの割当てです。char
型の配列は、新しいTLABを最も多くトリガーします。どれだけのメモリーがchar
型の配列として割り当てられているかは不明です。TLABのサイズは、char
型の配列によって割り当てられるメモリーを推定するのに役立ちます。
図2-11は、最も多くのメモリーを割り当てるchar
型の配列の例です。いずれかのクラスをクリックして、これらの割当てのスタック・トレースを参照してください。記録の例では、すべての割当てプレッシャの44%がchar
型の配列に由来し、27%がStringBuilder.toString
から呼び出されるArray.copyOfRange
に由来することを示しています。通常、StringBuilder.toString
は、Throwable.printStackTrace
およびStackTraceElement.toString
によって呼び出されます。これらのメソッドの呼出しを確認するには、さらに展開します。
注意: アプリケーションによる一時オブジェクトの割当てが多いほど、アプリケーションで必要なガベージ・コレクションが増えます。「割当て」タブは、ほとんどの割当てを見つけてアプリケーションのGCプレッジャを減らすことに役立ちます。「TLAB外の割当て」タブでは、通常、「新しいTLABの割当て」タブよりもメモリー・プレッシャが少ない、大きいメモリー割当てを参照できます。
「オブジェクト統計」タブ: 「オブジェクト統計」タブには、ほとんどのライブ・セットを持つクラスが表示されます。ライブ・セットについて理解するには、「「メモリー」タブ」の「ガベージ・コレクション」サブタブを参照してください。図2-12では、フライト記録のヒープ統計を示しています。データを表示するには、フライト記録のヒープ統計を有効にしてください。下部の「上位の増加」タブでは、フライト記録中に各オブジェクト・タイプのサイズがどれだけ増加したかを示しています。特定のオブジェクト・タイプのサイズが大きく増加した場合にはメモリー・リークを示していますが、わずかな変動は正常です。特に、標準Javaクラス以外の上位の増加を調査します。
「コード」タブのフライト記録を検査します。
「コード」タブには、アプリケーションが時間の大半を費やしている場所の情報が含まれます。「概要」サブタブには、最も多くの実行時間を費やしたパッケージおよびクラスが表示されます。これはサンプリングからのデータです。JFRでは、一定の間隔で実行中のスレッドのサンプルを取ります。実際のコードを実行しているスレッドのみがサンプリングされ、スリープ中、ロックまたはI/Oを待機中のスレッドは表示されません。
実際のコードを実行するためのアプリケーション時間の詳細は、「ホット・メソッド」サブタブを参照してください。
図2-13では、最も多くサンプリングされたメソッドを示しています。これらの呼出し元を確認するには、サンプルを展開します。HashMap.getEntry
の呼出しが多い場合は、最も多く呼び出したメソッドが見つかるまでこのノードを展開します。このタブは、アプリケーションのボトルネックを見つけるのに最適です。
「呼出しツリー」サブタブでは、同じイベントが下から(Thread.run
などから)順に表示されます。
「例外」サブタブには、スローされた例外が表示されます。デフォルトではエラーのみがログされますが、すべての例外を含めるには、新しい記録を開始するときにこの設定を変更します。
「コンパイル」サブタブには、アプリケーションが実行されていたときにコンパイルされたメソッドが表示されます。
「クラスのロード」サブタブには、時間の経過とともにロードされたクラス数、実際にロードされたクラスおよびアンロードされたクラスが表示されます。このサブタブは、記録の開始時にクラス・ロード・イベントが有効であった場合にのみ情報が表示されます。
これらのタブの詳細は、右上の疑問符をクリックして組込みのヘルプを参照してください。
「スレッド」タブのフライト記録を検査します。
「スレッド」タブには、スレッド、ロックの競合およびその他の待機時間に関する情報が含まれます。
「概要」サブタブには、CPU使用率およびスレッド数の経時的な推移が示されます。
「ホット・スレッド」サブタブには、ほとんどのコード実行を行うスレッドが表示されます。この情報は、「コード」タブの「ホット・メソッド」サブタブと同じサンプリング・データに基づいています。
「競合」タブは、ロックの競合に起因するボトルネックを見つけるのに役立ちます。
注意:
デフォルトでは、10msより長い同期イベントのみが記録されますが、記録の開始時にこのしきい値を下げることができます。「待機時間」サブタブは、たとえば、スリープまたは待機の呼出し、ソケットからの読取り、ファイルI/Oの待機など、その他の待機時間の原因を示します。
「スレッド・ダンプ」サブタブには、記録内でトリガーできる定期的なスレッド・ダンプが表示されます。
「ロック・インスタンス」サブタブには、同期のために最も待機しているオブジェクトの正確なインスタンスが表示されます。
これらのタブの詳細は、右上の疑問符をクリックして組込みのヘルプを参照してください。
「I/O」タブには、ファイルの読取り、ファイルの書込み、ソケットの読取りおよびソケットの書込みに関する情報が表示されます。
注意:
デフォルトでは、10msより長いイベントのみが表示されます。しきい値は、新しい記録を作成するときに変更できます。「システム」タブは、アプリケーションが実行されているマシンのCPU、メモリーおよびOSに関する詳細を提供します。
また、環境変数およびJVMと同時に実行されている他のプロセスも表示されます。
jcmd
ユーティリティを使用してJVMに診断コマンド・リクエストを送信し、JVMではこれらのリクエストを使用してJavaフライト記録の制御、トラブルシューティング、JVMおよびJavaアプリケーションの診断を行います。
jcmd
はJVMが実行されているものと同じマシン上で使用され、JVMの起動で使用されたものと同じ有効なユーザーおよびグループ識別子を持っている必要があります。
特殊コマンドjcmd <process id/main class> PerfCounter.print
は、プロセス内のすべてのパフォーマンス・カウンタを出力します。
コマンドjcmd <process id/main class> <command> [options]
は、JVMにコマンドを送信します。
次の例に、jcmd
ユーティリティによるJVMへの診断コマンド・リクエストを示します。
> jcmd 5485 sun.tools.jcmd.JCmd 2125 MyProgram > jcmd MyProgram help (or "jcmd 2125 help") 2125: The following commands are available: JFR.configure JFR.stop JFR.start JFR.dump JFR.check VM.log VM.native_memory VM.check_commercial_features VM.unlock_commercial_features ManagementAgent.status ManagementAgent.stop ManagementAgent.start_local ManagementAgent.start Compiler.directives_clear Compiler.directives_remove Compiler.directives_add Compiler.directives_print VM.print_touched_methods Compiler.codecache Compiler.codelist Compiler.queue VM.classloader_stats Thread.print JVMTI.data_dump JVMTI.agent_load VM.stringtable VM.symboltable VM.class_hierarchy GC.class_stats GC.class_histogram GC.heap_dump GC.finalizer_info GC.heap_info GC.run_finalization GC.run VM.info VM.uptime VM.dynlibs VM.set_flag VM.flags VM.system_properties VM.command_line VM.version help For more information about a specific command use 'help <command>'. > jcmd MyProgram help Thread.print 2125: Thread.print Print all threads with stacktraces. Impact: Medium: Depends on the number of threads. Permission: java.lang.management.ManagementPermission(monitor) Syntax : Thread.print [options] Options: (options must be specified using the <key> or <key>=<value> syntax) -l : [optional] print java.util.concurrent locks (BOOLEAN, false) > jcmd MyProgram Thread.print 2125: 2014-07-04 15:58:56 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.0-b69 mixed mode): ...
次の項では、jcmd
ユーティリティでの便利なコマンドおよびトラブルシューティング手法について説明します。
使用可能な診断コマンドはHotSpot VMのバージョンごとに異なる場合があるので、jcmd <process id/main class> help
を使用して、使用可能なすべてのオプションを確認することをお薦めします。
jcmd
ツールに含まれている非常に役立つコマンドの一部を次に示します。jcmd <process id/main class> help <command>
を使用すれば、該当するコマンドのその他のオプションをいつでも確認できることを覚えておいてください。
ネイティブ・メモリー・トラッキング(NMT)は、Java HotSpot VMの内部メモリー使用状況を追跡するJava HotSpot VM機能です。
NMTでは、非JVMコードによるメモリーの割当てを追跡しないので、ネイティブ・コードのメモリー・リークを検出するには、オペレーティング・システムでサポートされたツールの使用が必要になる場合があります。
次の項では、VM内部メモリー割当てのモニターおよびVMメモリー・リークの診断方法について説明します。
ネイティブ・メモリー・トラッキングを使用してメモリー・リークを検知する手順。
メモリー・リークを検出するには、次の手順を実行します。
-XX:NativeMemoryTracking=summary
または-XX:NativeMemoryTracking=detail
。jcmd <pid> VM.native_memory baseline
。jcmd <pid> VM.native_memory detail.diff
ネイティブ・メモリー・トラッキングはメモリーをモニターし、開発またはメンテナンス時にアプリケーションのメモリー使用量が増え始めないように設定できます。
NMTのメモリー・カテゴリの詳細は、表2-1を参照してください。
次の項では、NMTのサマリーまたは詳細データを取得する方法、およびサンプル出力の解釈の方法を説明します。
JDKダウンロードに含まれるもう1つの便利なツールは、JConsole
モニタリング・ツールです。このツールはJMXに準拠しています。このツールは、JVMの組込みJMXインストゥルメンテーションを使用して、実行中のアプリケーションのパフォーマンスやリソース消費に関する情報を提供します。
このツールは、JDKダウンロードに含まれてはいますが、JREで配備されたアプリケーションのモニターや管理にも使用できます。
JConsole
ツールは、スレッド使用量やメモリー消費量などの有用な情報、およびクラス・ロード、実行時コンパイル、オペレーティング・システムに関する詳細情報を表示する目的で、任意のJavaアプリケーションに接続できます。
この出力は、メモリー・リーク、過剰なクラス・ロードや実行中のスレッドなどの問題の高レベルの診断に役立ちます。これは、チューニングやヒープ・サイズ決定にも役立つ可能性があります。
JConsole
を使用すれば、モニタリングだけでなく、実行中のシステム内のいくつかのパラメータを動的に変更することもできます。たとえば、-verbose:gc
オプションの設定を変更できるので、実行中のアプリケーションに対するガベージ・コレクションのトレース出力を動的に有効または無効にできます。
次の項では、JConsoleツールによるトラブルシューティング手法について説明します。
JConsole
を使用して、データをモニターします。
次のリストは、JConsole
ツールを使用してモニターできるデータの概要を示しています。各見出しはツール内のタブ・ペインに対応しています。
概要
このペインには、ヒープ・メモリー使用量、スレッド数、クラス数、およびCPU使用率の経時的推移を示すグラフが表示されます。この概要では、いくつかのリソースのアクティビティを一度に視覚化できます。
メモリー
選択された1つのメモリー領域(ヒープ、非ヒープ、各種メモリー・プール)について
メモリー使用量の経時的推移を示すグラフ
現在のメモリー・サイズ
コミットされたメモリーの量
最大メモリー・サイズ
ガベージ・コレクタの情報(実行されたコレクションの回数や、ガベージ・コレクションの実行に費やされた合計時間など)
現在使用中のヒープおよび非ヒープ・メモリーのパーセントを示すグラフ
さらにこのペインでは、ガベージ・コレクションの実行を要求できます。
スレッド
スレッド使用量の経時的推移を示すグラフ。
ライブ・スレッド: 現在のライブ・スレッド数。
ピーク: JVM起動後のライブ・スレッドの最大数。
選択された1つのスレッドの名前、状態、およびスタック・トレース、およびブロックされたスレッドの場合は、スレッドが獲得を待機しているシンクロナイザとロックを所有しているスレッド。
「デッドロックの検出」ボタンは、デッドロック検出を実行する要求をターゲット・アプリケーションに送信し、各デッドロック・サイクルをそれぞれ異なるタブに表示します。
クラス
ロード済クラス数の経時的推移を示すグラフ
現在メモリーにロードされているクラスの数
JVMの起動後にメモリーにロードされたクラスの合計数(その後アンロードされたものも含む)
JVMの起動後にメモリーからアンロードされたクラスの合計数
VMサマリー
一般的な情報(JConsole接続データ、JVMの稼働時間、JVMで消費されたCPU時間、コンパイラ名、合計コンパイル時間など)。
スレッドおよびクラスのサマリー情報
メモリーおよびガベージ・コレクションの情報(ファイナライズ保留中のオブジェクトの数など)
オペレーティング・システムに関する情報(物理特性、実行中のプロセス用の仮想メモリー量、スワップ領域など)
JVM自体に関する情報(引数やクラス・パスなど)
MBeans
このペインには、接続済のJMXエージェントに登録されたすべてのプラットフォームおよびアプリケーションMBeanを示すツリー構造が表示されます。ツリー内でMBeanを選択すると、その属性、操作、通知、およびその他の情報が表示されます。
操作(存在する場合)を呼び出せます。たとえば、com.sun.management
ドメインに含まれるHotSpotDiagnostic
MBeanの操作dumpHeap
は、ヒープ・ダンプを実行します。この操作の入力パラメータは、ターゲットVMが実行されているマシン上でのヒープ・ダンプ・ファイルのパス名になります。
書込み可能な属性値を設定できます。たとえば、特定のVMフラグの値を設定、設定解除、または変更するには、HotSpotDiagnostic
MBeanのsetVMOption
操作を呼び出します。フラグは、DiagnosticOptions
属性の値のリストによって示されます。
通知(存在する場合)をサブスクライブするには、「サブスクライブ」および「サブスクライブ解除」ボタンを使用します。
JConsoleは、ローカル・アプリケーションとリモート・アプリケーションの両方をモニターできます。接続先JMXエージェントを指定する引数付きでツールを起動した場合、ツールは指定されたアプリケーションのモニタリングを自動的に開始します。
ローカル・アプリケーションをモニターするには、コマンドjconsolepid
(pid
はアプリケーションのプロセスID)を実行します。
リモート・アプリケーションをモニターするには、コマンドjconsolehostname:
portnumber (hostname
はアプリケーションを実行しているホストの名前、portnumber
はJMXエージェントの有効化時に指定したポート番号)を実行します。
jconsole
コマンドを引数なしで実行した場合、このツールはまず、モニター対象のローカルまたはリモート・プロセスを指定するための「新規接続」ウィンドウを表示します。「接続」メニューを使えば別のホストにいつでも接続できます。
最新のJDKリリースでは、モニター対象アプリケーションを起動する際にオプションは不要です。
モニタリング・ツールの出力例として、図2-15はヒープ・メモリー使用量のグラフを示しています。
jdb
ユーティリティは、コマンド行デバッガの例としてJDKに含まれています。jdb
ユーティリティは、Java Debug Interface (JDI)を使ってターゲットJVMを起動または接続します。
$JAVA_HOME/demo/jpda/examples.jar
にはjdb
のソース・コードが含まれています。
JDIは、(通常はリモートの)仮想マシンの実行状態にアクセスする必要があるデバッガや同様のシステムに役立つ情報を提供する、高レベルのJava APIです。JDIはJava Platform Debugger Architecture (JPDA)のコンポーネントです。「Java Platform Debugger Architecture」を参照してください。
次の項では、jdb
ユーティリティのトラブルシューティング手法を提供します。
jdbユーティリティはリモート・デバッグに使用するデバッガ・コネクタをモニターするために使用します。
JDIでは、コネクタを使用してデバッガをターゲットJVMに接続します。JDKには従来、ターゲットJVMとのデバッグ・セッションを開始して確立するコネクタと、(TCP/IPまたは共有メモリー・トランスポートを使用した)リモート・デバッグに使用されるコネクタが付属しています。
JDKにはさらに、Java言語デバッガからクラッシュ・ダンプやハングアップ・プロセスに接続することを許可する、Serviceability Agent (SA)コネクタもいくつか付属しています。これは、クラッシュまたはハング・アップの際にアプリケーションが何をしていたのかを確認するのに役立つ可能性があります。
これらのコネクタはSACoreAttachingConnector
、SADebugServerAttachingConnector
、およびSAPIDAttachingConnector
です。
これらのコネクタは通常、NetBeans統合開発環境(IDE)や商用IDEなどのエンタープライズ・デバッガで使用されます。次の項では、jdb
コマンド行デバッガでこれらのコネクタを使用する方法を示します。
コマンドjdb -listconnectors
は、使用可能なコネクタの一覧を出力します。コマンドjdb -help
は、コマンドの使用方法のヘルプを出力します。
Java Platform, Standard Editionツール・リファレンスのjdbユーティリティに関する項を参照してください
次の例では、SA PID接続コネクタを使用してプロセスに接続します。ターゲット・プロセスは特別なオプションを使用して起動されるわけではありません。つまり、-agentlib:jdwp
オプションは必要ありません。このコネクタがプロセスに接続するときは、読取り専用モードで行われます。つまり、デバッガはスレッドや実行中のアプリケーションを調べることはできますが、何も変更できません。デバッガが接続されている間、プロセスは休止しています。
次の例のコマンドは、sun.jvm.hotspot.jdi.SAPIDAttachingConnector
という名前のコネクタを使用するようにjdb
に指示しています。これはクラス名ではなくコネクタ名です。コネクタはpid
という引数を1つ取り、その値はターゲット・プロセスのプロセスID (9302
)です。
$jdb -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=9302
Initializing jdb ... >threads
Group system: (java.lang.ref.Reference$ReferenceHandler)0xa Reference Handler unknown (java.lang.ref.Finalizer$FinalizerThread)0x9 Finalizer unknown (java.lang.Thread)0x8 Signal Dispatcher running (java.lang.Thread)0x7 Java2D Disposer unknown (java.lang.Thread)0x2 TimerQueue unknown Group main: (java.lang.Thread)0x6 AWT-XAWT running (java.lang.Thread)0x5 AWT-Shutdown unknown (java.awt.EventDispatchThread)0x4 AWT-EventQueue-0 unknown (java.lang.Thread)0x3 DestroyJavaVM running (sun.awt.image.ImageFetcher)0x1 Image Animator 0 sleeping (java.lang.Thread)0x0 Intro running >thread 0x7
Java2D Disposer[1]where
[1] java.lang.Object.wait (native method) [2] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:116) [3] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:132) [4] sun.java2d.Disposer.run (Disposer.java:125) [5] java.lang.Thread.run (Thread.java:619) Java2D Disposer[1]up 1
Java2D Disposer[2]where
[2] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:116) [3] java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:132) [4] sun.java2d.Disposer.run (Disposer.java:125) [5] java.lang.Thread.run (Thread.java:619)
この例では、threads
コマンドを使用してすべてのスレッドの一覧を取得しています。次に、thread 0x7
コマンドで特定のスレッドを選択し、where
コマンドを使用してスレッド・ダンプを取得しています。次に、up 1
コマンドを使用してスタック内で1フレーム上に移動し、where
コマンドを再度使用してスレッド・ダンプを取得しています。
SAコア接続コネクタは、デバッガをコア・ファイルに接続するために使用されます。
クラッシュの後にコア・ファイルが作成されている場合があります。「システム・クラッシュのトラブルシューティング」を参照してください。コア・ファイルは、gcore
コマンド(Oracle Solarisオペレーティング・システムの場合)、またはgdb
のgcore
コマンド(Linuxの場合)を使用して取得することもできます。コア・ファイルはそのコア・ファイルが作成された時点のプロセスのスナップショットであるため、コネクタは読取り専用モードで接続します。つまり、デバッガはクラッシュ発生時のスレッドや実行中のアプリケーションを調べることができます。
次の例のコマンドは、sun.jvm.hotspot.jdi.SACoreAttachingConnector
という名前のコネクタを使用するようにjdb
に指示しています。このコネクタはjavaExecutable
、core
という2つの引数を取ります。javaExecutable
引数はJavaバイナリの名前を示します。core
引数は、コア・ファイル名です(次の例に示すように、PID 20441を持つプロセスからのコア)。
$ jdb -connect sun.jvm.hotspot.jdi.SACoreAttachingConnector:javaExecutable=$JAVA_HOME/bin/java,core=core.20441
デバッガがインストールされたマシン上で、SAデバッグ・サーバー接続コネクタを使用してデバッグ・サーバーに接続できます。
別のマシンからトランスポートされたコア・ファイルをデバッグするには、オペレーティング・システムのバージョンとライブラリが一致する必要があります。この場合はまず、SAデバッグ・サーバーという名前のプロキシ・サーバーを実行できます。その後、デバッガがインストールされたマシン上で、SAデバッグ・サーバー接続コネクタを使ってデバッグ・サーバーに接続できます。
たとえば、マシン1、マシン2という2つのマシンがあるとします。マシン1でコア・ファイルが使用可能、マシン2でデバッガが使用可能です。次の例に示すように、マシン1でSAデバッグ・サーバーが起動されます。
$ jsadebugd $JAVA_HOME/bin/java core.20441
jsadebugd
コマンドは2つの引数を取ります。最初の引数は実行可能ファイルの名前です。通常、これはjava
ですが、別の名前のこともあります(埋込みVMの場合など)。2番目の引数は、コア・ファイルの名前です。この例でのコア・ファイルは、gcore
ユーティリティを使用してPID 20441のプロセスに対して取得されました。
次の例に示すように、マシン2では、デバッガはSAデバッグ・サーバー接続コネクタを使用してリモートSAデバッグ・サーバーに接続します。
$ jdb -connect sun.jvm.hotspot.jdi.SADebugServerAttachingConnector:debugServerName=machine1
この例のコマンドは、sun.jvm.hotspot.jdi.SADebugServerAttachingConnector
という名前のコネクタを使用するようにjdb
に指示しています。このコネクタは、debugServerName
という引数(SAデバッグ・サーバーが実行されているマシンのホスト名またはIPアドレス)を1つ持ちます。
注意:
SAデバッグ・サーバーはハングアップ・プロセスのリモート・デバッグにも使用できます。その場合、単一の引数(プロセスのPID)を取ります。さらに、同じマシン上で複数のデバッグ・サーバーを実行する必要がある場合は、それぞれに一意のIDを指定する必要があります。SAデバッグ・サーバー接続コネクタで、このIDは追加のコネクタ引数として提供されます。
jinfo
コマンド行ユーティリティは、実行中のJavaプロセスまたはクラッシュ・ダンプから構成情報を取得し、JVMの起動時に使用されたシステム・プロパティまたはコマンド行フラグを出力します。
JVMおよびJavaアプリケーションに関する問題を診断するには、Java Mission Control、Java Flight Recorderおよびjcmd
ユーティリティを使用できます。診断機能を強化し、パフォーマンスのオーバーヘッドを削減するには、以前のjinfo
ユーティリティのかわりに最新のユーティリティjcmd
を使用してください。
jinfo
ユーティリティでは、jsadebugd
デーモンを使用してリモート・マシン上のプロセスやコア・ファイルを照会することもできます。注意:
この場合、出力に時間がかかります。jinfo
ユーティリティの-flag
オプションを使用すれば、指定されたJavaプロセスの特定のJVMフラグの値を動的に設定、設定解除、または変更できます。「Java HotSpot VMコマンド行オプション」を参照してください。
次の例は、PID番号が29620のJavaプロセスのjinfo
ユーティリティの出力を示しています。
$ jinfo 29620
Attaching to process ID 29620, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.6.0-rc-b100
Java System Properties:
java.runtime.name = Java(TM) SE Runtime Environment
sun.boot.library.path = /usr/jdk/instances/jdk1.6.0/jre/lib/sparc
java.vm.version = 1.6.0-rc-b100
java.vm.vendor = Sun Microsystems Inc.
java.vendor.url = http://java.sun.com/
path.separator = :
java.vm.name = Java HotSpot(TM) Client VM
file.encoding.pkg = sun.io
sun.java.launcher = SUN_STANDARD
sun.os.patch.level = unknown
java.vm.specification.name = Java Virtual Machine Specification
user.dir = /home/js159705
java.runtime.version = 1.6.0-rc-b100
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
java.endorsed.dirs = /usr/jdk/instances/jdk1.6.0/jre/lib/endorsed
os.arch = sparc
java.io.tmpdir = /var/tmp/
line.separator =
java.vm.specification.vendor = Sun Microsystems Inc.
os.name = SunOS
sun.jnu.encoding = ISO646-US
java.library.path = /usr/jdk/instances/jdk1.6.0/jre/lib/sparc/client:/usr/jdk/instances/jdk1.6.0/jre/lib/sparc:
/usr/jdk/instances/jdk1.6.0/jre/../lib/sparc:/net/gtee.sfbay/usr/sge/sge6/lib/sol-sparc64:
/usr/jdk/packages/lib/sparc:/lib:/usr/lib
java.specification.name = Java Platform API Specification
java.class.version = 50.0
sun.management.compiler = HotSpot Client Compiler
os.version = 5.10
user.home = /home/js159705
user.timezone = US/Pacific
java.awt.printerjob = sun.print.PSPrinterJob
file.encoding = ISO646-US
java.specification.version = 1.6
java.class.path = /usr/jdk/jdk1.6.0/demo/jfc/Java2D/Java2Demo.jar
user.name = js159705
java.vm.specification.version = 1.0
java.home = /usr/jdk/instances/jdk1.6.0/jre
sun.arch.data.model = 32
user.language = en
java.specification.vendor = Sun Microsystems Inc.
java.vm.info = mixed mode, sharing
java.version = 1.6.0-rc
java.ext.dirs = /usr/jdk/instances/jdk1.6.0/jre/lib/ext:/usr/jdk/packages/lib/ext
sun.boot.class.path = /usr/jdk/instances/jdk1.6.0/jre/lib/resources.jar:
/usr/jdk/instances/jdk1.6.0/jre/lib/rt.jar:/usr/jdk/instances/jdk1.6.0/jre/lib/sunrsasign.jar:
/usr/jdk/instances/jdk1.6.0/jre/lib/jsse.jar:
/usr/jdk/instances/jdk1.6.0/jre/lib/jce.jar:/usr/jdk/instances/jdk1.6.0/jre/lib/charsets.jar:
/usr/jdk/instances/jdk1.6.0/jre/classes
java.vendor = Sun Microsystems Inc.
file.separator = /
java.vendor.url.bug = http://java.sun.com/cgi-bin/bugreport.cgi
sun.io.unicode.encoding = UnicodeBig
sun.cpu.endian = big
sun.cpu.isalist =
VM Flags:
次のトピックでは、jinfo
ユーティリティによるトラブルシューティング手法について説明します。
jinfo
の出力には、java.class.path
およびsun.boot.class.path
の設定が表示されます。
ターゲットJVMを-classpath
および-Xbootclasspath
引数付きで起動した場合、jinfo
の出力にはjava.class.path
とsun.boot.class.path
の設定が含まれます。この情報は、クラス・ローダーの問題を調査する際に必要となる可能性があります。
jinfo
ツールは、プロセスから情報を取得するだけでなく、コア・ファイルを入力として使用できます。たとえば、Oracle Solarisオペレーティング・システムの場合、前述の例ではgcore
ユーティリティを使用してプロセスのコア・ファイルを取得できます。コア・ファイルの名前はcore.29620
となり、プロセスの作業ディレクトリ内に生成されます。次の例に示すように、Java実行可能ファイルとコア・ファイルへのパスを、jinfo
ユーティリティの引数として指定する必要があります。
$ jinfo $JAVA_HOME/bin/java core.29620
バイナリ名はjava
でないことがあります。これは、JNI呼び出しAPIを使用してVMが作成されたときに発生します。jinfo
ツールでは、コア・ファイルの生成元のバイナリが必要です。
jmap
コマンド行ユーティリティは、実行中のVMまたはコア・ファイルのメモリー関係の統計を出力します。
このユーティリティは、jsadebugd
デーモンを使ってリモート・マシン上のプロセスやコア・ファイルを照会することもできます。この場合、出力に時間がかかります。
JVMおよびJavaアプリケーションに関する問題を診断するには、Java Mission Control、Java Flight Recorderおよびjcmd
ユーティリティを使用できます。診断機能を強化し、パフォーマンスのオーバーヘッドを削減するには、以前のjmap
ユーティリティのかわりに最新のユーティリティjcmd
の使用をお薦めします。
プロセスまたはコア・ファイルでコマンド行オプションなしでjmap
を使用された場合、ロードされた共有オブジェクトの一覧が出力されます(出力はOracle Solarisオペレーティング・システムのpmap
ユーティリティに似ています)。より詳細な情報を得るために、オプション-heap
、-histo
、または-permstat
を使用できます。これらのオプションについては、以降の各サブセクションで説明します。
さらに、JDK 7リリースで導入された-dump:format=b,file=filename
オプションを使用すると、jmap
によって、Javaヒープが指定されたファイルにバイナリ形式でダンプされます。
ハングアップ・プロセスが原因でjmappid
コマンドが反応しない場合は、-F
オプションを使用して(Oracle SolarisおよびLinuxオペレーティング・システムのみ) Serviceability Agentの使用を強制できます。
次の項では、jmap
コマンドの使用方法およびトラブルシューティング手法について説明し、実行中のVMまたはコア・ファイルのメモリー関連の統計情報を出力する例を示します。
jmap -heap
コマンドを使用してJavaヒープ情報を取得します。
次のJavaヒープ情報を取得するには、-heap
オプションを使用します。
ガベージ・コレクション(GC)アルゴリズムに固有の情報。GCアルゴリズムの名前(パラレルGCなど)やアルゴリズム固有の詳細(パラレルGCのスレッド数など)が含まれます。
コマンド行オプションとして指定されたか、またはマシンの構成に基づいてVMによって選択された可能性のあるヒープ構成。
ヒープ使用量のサマリー: このツールは、各世代(ヒープ領域)について、合計ヒープ容量、使用中のメモリー、および使用可能な空きメモリーを出力します。領域の集まりとして構成された世代(New世代など)では、領域固有のメモリー・サイズ・サマリーが含まれます。
次の例は、jmap -heap
コマンドの出力を示しています。
$ jmap -heap 29620
Attaching to process ID 29620, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.6.0-rc-b100
using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 67108864 (64.0MB)
NewSize = 2228224 (2.125MB)
MaxNewSize = 4294901760 (4095.9375MB)
OldSize = 4194304 (4.0MB)
NewRatio = 8
SurvivorRatio = 8
PermSize = 12582912 (12.0MB)
MaxPermSize = 67108864 (64.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 2031616 (1.9375MB)
used = 70984 (0.06769561767578125MB)
free = 1960632 (1.8698043823242188MB)
3.4939673639112905% used
Eden Space:
capacity = 1835008 (1.75MB)
used = 36152 (0.03447723388671875MB)
free = 1798856 (1.7155227661132812MB)
1.9701276506696428% used
From Space:
capacity = 196608 (0.1875MB)
used = 34832 (0.0332183837890625MB)
free = 161776 (0.1542816162109375MB)
17.716471354166668% used
To Space:
capacity = 196608 (0.1875MB)
used = 0 (0.0MB)
free = 196608 (0.1875MB)
0.0% used
tenured generation:
capacity = 15966208 (15.2265625MB)
used = 9577760 (9.134063720703125MB)
free = 6388448 (6.092498779296875MB)
59.98769400974859% used
Perm Generation:
capacity = 12582912 (12.0MB)
used = 1469408 (1.401336669921875MB)
free = 11113504 (10.598663330078125MB)
11.677805582682291% used
-histo
オプションを指定してjmap
コマンドを使用すると、クラス固有のヒープ・ヒストグラムを取得できます。
指定されたパラメータに応じて、jmap -histo
コマンドは実行中のプロセスまたはコア・ファイルのヒープ・ヒストグラムを出力できます。
実行中のプロセスに対してコマンドが実行されると、ツールはクラスごとにオブジェクト数、メモリー・サイズ(バイト)、および完全修飾クラス名を出力します。Java HotSpot VMの内部クラスは山カッコで囲まれます。ヒストグラムは、ヒープがどのように使用されているかを理解するのに役立ちます。オブジェクトのサイズを得るには、合計サイズをそのオブジェクト型の数で割る必要があります。
次の例は、29620というPID番号を持つプロセスに対してjmap -histo
コマンドを実行した場合の出力を示しています。
$ jmap -histo 29620
num #instances #bytes class name
--------------------------------------
1: 1414 6013016 [I
2: 793 482888 [B
3: 2502 334928 <constMethodKlass>
4: 280 274976 <instanceKlassKlass>
5: 324 227152 [D
6: 2502 200896 <methodKlass>
7: 2094 187496 [C
8: 280 172248 <constantPoolKlass>
9: 3767 139000 [Ljava.lang.Object;
10: 260 122416 <constantPoolCacheKlass>
11: 3304 112864 <symbolKlass>
12: 160 72960 java2d.Tools$3
13: 192 61440 <objArrayKlassKlass>
14: 219 55640 [F
15: 2114 50736 java.lang.String
16: 2079 49896 java.util.HashMap$Entry
17: 528 48344 [S
18: 1940 46560 java.util.Hashtable$Entry
19: 481 46176 java.lang.Class
20: 92 43424 javax.swing.plaf.metal.MetalScrollButton
... more lines removed here to reduce output...
1118: 1 8 java.util.Hashtable$EmptyIterator
1119: 1 8 sun.java2d.pipe.SolidTextRenderer
Total 61297 10152040
コア・ファイルに対してjmap -histo
コマンドが実行された場合、ツールはクラスごとにサイズ、カウント、クラス名を出力します。Java HotSpot VMの内部クラスには、先頭にアスタリスク(*)が付けられます。
jmap -histo
コマンドをコア・ファイルで実行した場合の出力を示します。
& jmap -histo /net/koori.sfbay/onestop/jdk/6.0/promoted/all/b100/binaries/solaris-sparcv9/bin/java core
Attaching to core core from executable /net/koori.sfbay/onestop/jdk/6.0/
promoted/all/b100/binaries/solaris-sparcv9/bin/java, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 1.6.0-rc-b100
Iterating over heap. This may take a while...
Heap traversal took 8.902 seconds.
Object Histogram:
Size Count Class description
-------------------------------------------------------
4151816 2941 int[]
2997816 26403 * ConstMethodKlass
2118728 26403 * MethodKlass
1613184 39750 * SymbolKlass
1268896 2011 * ConstantPoolKlass
1097040 2011 * InstanceKlassKlass
882048 1906 * ConstantPoolCacheKlass
758424 7572 char[]
733776 2518 byte[]
252240 3260 short[]
214944 2239 java.lang.Class
177448 3341 * System ObjArray
176832 7368 java.lang.String
137792 3756 java.lang.Object[]
121744 74 long[]
72960 160 java2d.Tools$3
63680 199 * ObjArrayKlassKlass
53264 158 float[]
... more lines removed here to reduce output...
Permanent世代は、クラスやメソッド・オブジェクトなどの仮想マシン自体を反映したデータをすべて保持するヒープ領域です。
この領域は、Java仮想マシン仕様ではメソッド領域とも呼ばれます。
非常に多くのクラスを動的に生成してロードするアプリケーション(Java Server PagesやWebコンテナなど)では、Permanent世代のサイズの構成が重要になる可能性があります。アプリケーションでロードされたクラスが多すぎた場合、そのアプリケーションは次のエラーで終了する可能性があります。
Exception in thread thread_name java.lang.OutOfMemoryError: PermGen space
「OutOfMemoryError例外の理解」を参照してください。
Permanent世代に関する詳細情報を得るには、jmap
コマンドの-permstat
オプションを使ってPermanent世代内のオブジェクトの統計を出力できます。
次の例は、29620というPID番号を持つプロセスに対して実行されたjmap -permstat
コマンドの出力を示しています。
$ jmap -permstat 29620
Attaching to process ID 29620, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.6.0-rc-b100
12674 intern Strings occupying 1082616 bytes.
finding class loader instances ..Unknown oop at 0xd0400900
Oop's klass is 0xd0bf8408
Unknown oop at 0xd0401100
Oop's klass is null
done.
computing per loader stat ..done.
please wait.. computing liveness.........................................done.
class_loader classes bytes parent_loader alive? type
<bootstrap> 1846 5321080 null live <internal>
0xd0bf3828 0 0 null live sun/misc/Launcher$ExtClassLoader@0xd8c98c78
0xd0d2f370 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0c99280 1 1440 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0b71d90 0 0 0xd0b5b9c0 live java/util/ResourceBundle$RBClassLoader@0xd8d042e8
0xd0d2f4c0 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0b5bf98 1 920 0xd0b5bf38 dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0c99248 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f488 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0b5bf38 6 11832 0xd0b5b9c0 dead sun/reflect/misc/MethodUtil@0xd8e8e560
0xd0d2f338 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f418 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f3a8 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0b5b9c0 317 1397448 0xd0bf3828 live sun/misc/Launcher$AppClassLoader@0xd8cb83d8
0xd0d2f300 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f3e0 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0ec3968 1 1440 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0e0a248 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0c99210 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f450 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0d2f4f8 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
0xd0e0a280 1 904 null dead sun/reflect/DelegatingClassLoader@0xd8c22f50
total = 22 2186 6746816 N/A alive=4, dead=18 N/A
クラス・ローダー・オブジェクトごとに次の詳細が出力されます。
クラス・ローダー・オブジェクトのアドレス(ユーティリティが実行されたスナップショット時点)
ロードされたクラスの数
このクラス・ローダーによってロードされたすべてのクラスのメタデータで消費されているバイト数(概算)
親クラス・ローダー(存在する場合)のアドレス
ローダー・オブジェクトが将来ガベージ・コレクトされるかどうかを示すliveまたはdeadマーク
このクラス・ローダーのクラス名
jps
ユーティリティは、ターゲット・システム上の現在のユーザーで計測されたすべてのJava HotSpot VMを一覧表示します。
VMが埋め込まれた環境、つまりjava
起動ツールではなくJNI呼出しAPIを使用してVMが起動される環境では、このユーティリティが非常に役立ちます。こうした環境では、プロセス・リスト内でJavaプロセスを認識するのが常に容易であるとはかぎりません。
次の例は、jps
ユーティリティの使用方法を示しています。
$ jps
16217 MyApplication
16342 jps
jps
ユーティリティは、ユーザーがアクセス権を持つ仮想マシンを一覧表示します。この判断には、オペレーティング・システムに固有のアクセス制御メカニズムが使用されます。たとえば、Oracle Solarisオペレーティング・システム上のroot以外のユーザーがjps
ユーティリティは、ユーザーがアクセス権を持つ仮想マシンを一覧表示します。ユーティリティを実行した場合、出力はそのユーザーのUIDで起動された仮想マシンの一覧になります。
このユーティリティには、PIDの一覧表示に加え、アプリケーションのmain
メソッドに渡された引数、VM引数の完全なリスト、アプリケーションのmain
クラスの完全なパッケージ名を出力するオプションも用意されています。また、リモート・システム上でjstatd
デーモンが実行されていれば、jps
ユーティリティはリモート・システム上のプロセスを一覧表示することもできます。
システム上でいくつかのJava Web Startアプリケーションを実行している場合、次の例に示すように、それらは同じに見えてしまいがちです。
$ jps
1271 jps
1269 Main
1190 Main
この場合、次の例に示すようにjps -m
を使用して区別します。
$ jps -m
1271 jps -m
1269 Main http://bugster.central.sun.com/bugster.jnlp
1190 Main http://webbugs.sfbay/IncidentManager/incident.jnlp
JVMおよびJavaアプリケーションの問題を診断するには、jstack
ユーティリティではなくjcmd
ユーティリティを使用してください。
JVMおよびJavaアプリケーションに関する問題を診断するには、Java Mission Control、Java Flight Recorderおよびjcmd
ユーティリティを使用できます。診断機能を強化し、パフォーマンスのオーバーヘッドを削減するには、以前のjstack
,ユーティリティのかわりに最新のユーティリティjcmd
の使用をお薦めします。
次の項では、jstack
ユーティリティによるトラブルシューティング手法について説明します。
jstack
コマンド行ユーティリティは、指定されたプロセスまたはコア・ファイルに接続し、仮想マシンに接続されたすべてのスレッド(JavaスレッドやVM内部スレッドも含む)のスタック・トレースを出力する以外に、オプションでネイティブ・スタック・フレームも出力します。このユーティリティではデッドロック検出も実行されます。
このユーティリティは、jsadebugd
デーモンを使ってリモート・マシン上のプロセスやコア・ファイルを照会することもできます。この場合、出力に時間がかかります。
すべてのスレッドのスタック・トレースは、デッドロックやハングアップなど、いくつかの問題の診断に役立つ可能性があります。
-l
オプションは、所有可能なシンクロナイザをヒープ内で探してjava.util.concurrent.locks
に関する情報を出力するように、ユーティリティに指示します。このオプションがない場合、スレッド・ダンプにはモニターの情報のみが含まれます。
jstack pid
オプションの出力は、アプリケーション・コンソール(標準入力)で[Ctrl]+[\]を押すか、プロセスにquitシグナルを送信した場合に得られるものと同じです。出力例については、「Ctrl+Breakハンドラ」を参照してください。
スレッド・ダンプは、プログラム内でThread.getAllStackTraces
メソッドを使って、またはデバッガ内ですべてのスレッド・スタックを出力するデバッガ・オプション(jdb
サンプル・デバッガの場合はwhere
コマンド)を使って取得することもできます。
コア・ダンプからスタック・トレースを取得するにはjstack
コマンドを使用します。
コア・ダンプからスタック・トレースを取得するには、次の例のように、コア・ファイルでjstack
コマンドを実行します。
$ jstack $JAVA_HOME/bin/java core
jstack
ユーティリティは、混合スタックの出力に使用することもできます(つまり、Javaスタックの他にネイティブ・スタック・フレームも出力できます)。ネイティブ・フレームとは、VMコードやJNI/ネイティブ・コードに関連付けられたC/C++フレームのことです。
混合スタックを出力するには、次の例に示すように-m
オプションを使用します。
$ jstack -m 21177
Attaching to process ID 21177, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.6.0-rc-b100
Deadlock Detection:
Found one Java-level deadlock:
=============================
"Thread1":
waiting to lock Monitor@0x0005c750 (Object@0xd4405938, a java/lang/String),
which is held by "Thread2"
"Thread2":
waiting to lock Monitor@0x0005c6e8 (Object@0xd4405900, a java/lang/String),
which is held by "Thread1"
Found a total of 1 deadlock.
----------------- t@1 -----------------
0xff2c0fbc __lwp_wait + 0x4
0xff2bc9bc _thrp_join + 0x34
0xff2bcb28 thr_join + 0x10
0x00018a04 ContinueInNewThread + 0x30
0x00012480 main + 0xeb0
0x000111a0 _start + 0x108
----------------- t@2 -----------------
0xff2c1070 ___lwp_cond_wait + 0x4
0xfec03638 bool Monitor::wait(bool,long) + 0x420
0xfec9e2c8 bool Threads::destroy_vm() + 0xa4
0xfe93ad5c jni_DestroyJavaVM + 0x1bc
0x00013ac0 JavaMain + 0x1600
0xff2bfd9c _lwp_start
----------------- t@3 -----------------
0xff2c1070 ___lwp_cond_wait + 0x4
0xff2ac104 _lwp_cond_timedwait + 0x1c
0xfec034f4 bool Monitor::wait(bool,long) + 0x2dc
0xfece60bc void VMThread::loop() + 0x1b8
0xfe8b66a4 void VMThread::run() + 0x98
0xfec139f4 java_start + 0x118
0xff2bfd9c _lwp_start
----------------- t@4 -----------------
0xff2c1070 ___lwp_cond_wait + 0x4
0xfec195e8 void os::PlatformEvent::park() + 0xf0
0xfec88464 void ObjectMonitor::wait(long long,bool,Thread*) + 0x548
0xfe8cb974 void ObjectSynchronizer::wait(Handle,long long,Thread*) + 0x148
0xfe8cb508 JVM_MonitorWait + 0x29c
0xfc40e548 * java.lang.Object.wait(long) bci:0 (Interpreted frame)
0xfc40e4f4 * java.lang.Object.wait(long) bci:0 (Interpreted frame)
0xfc405a10 * java.lang.Object.wait() bci:2 line:485 (Interpreted frame)
... more lines removed here to reduce output...
----------------- t@12 -----------------
0xff2bfe3c __lwp_park + 0x10
0xfe9925e4 AttachOperation*AttachListener::dequeue() + 0x148
0xfe99115c void attach_listener_thread_entry(JavaThread*,Thread*) + 0x1fc
0xfec99ad8 void JavaThread::thread_main_inner() + 0x48
0xfec139f4 java_start + 0x118
0xff2bfd9c _lwp_start
----------------- t@13 -----------------
0xff2c1500 _door_return + 0xc
----------------- t@14 -----------------
0xff2c1500 _door_return + 0xc
先頭にアスタリスク(*)が付いているフレームがJavaフレーム、先頭にアスタリスクが付いていないフレームがネイティブC/C++フレームです。
このユーティリティの出力をc++filt
によってパイプで連結すると、C++分解シンボル名を分解解除できます。Java HotSpot VMはC++言語で開発されているため、jstack
ユーティリティはJava HotSpotの内部関数のC++分解シンボル名を出力します。
c++filt
ユーティリティは、SUNWspro
(Oracle Solarisオペレーティング・システムの場合)やgnu
(Linuxの場合)というネイティブC++コンパイラ・スイートとともに配布されます。
jstat
ユーティリティは、Java HotSpot VMの組込みインストゥルメンテーションを使用して、実行中アプリケーションのパフォーマンスやリソース消費に関する情報を提供します。
このツールは、パフォーマンスの問題、特にヒープ・サイズ決定やガベージ・コレクションに関係する問題を診断するときに使用できます。jstat
ユーティリティでは、特殊なオプション付きでVMを起動する必要はありません。Java HotSpot VMの組込みインストゥルメンテーションはデフォルトで有効になります。このユーティリティは、Oracleがサポートしているすべてのオペレーティング・システム・プラットフォームのJDKダウンロードに含まれています。
注意:
FAT32ファイル・システム上では、インストゥルメンテーションにアクセスできません。
Java Platform, Standard Editionツール・リファレンスのjstatに関する項を参照してください。
jstat
ユーティリティは、仮想マシン識別子(VMID)を使用してターゲット・プロセスを識別します。ドキュメントにはVMIDの構文が記載されていますが、それに必要な唯一のコンポーネントはローカル仮想マシン識別子(LVMID)です。LVMIDは、(必ずではありませんが、)一般的にはターゲットJVMプロセスに対するオペレーティング・システムのPIDです。
jstat
ユーティリティで提供されるデータは、Oracle SolarisおよびLinuxオペレーティング・システムのvmstat
およびiostat
で提供されるデータに似ています。
データをグラフィカルに表現する場合は、visualgc
ツールを使用できます。「visualgcツール」を参照してください。
-gcutil
オプションの使用例を次に示します。この例では、jstat
ユーティリティがLVMID番号2834に接続し、250ミリ秒間隔で7つのサンプルを取っています。
$ jstat -gcutil 2834 250 7
S0 S1 E O M YGC YGCT FGC FGCT GCT
0.00 99.74 13.49 7.86 95.82 3 0.124 0 0.000 0.124
0.00 99.74 13.49 7.86 95.82 3 0.124 0 0.000 0.124
0.00 99.74 13.49 7.86 95.82 3 0.124 0 0.000 0.124
0.00 99.74 13.49 7.86 95.82 3 0.124 0 0.000 0.124
0.00 99.74 13.49 7.86 95.82 3 0.124 0 0.000 0.124
0.00 99.74 13.49 7.86 95.82 3 0.124 0 0.000 0.124
0.00 99.74 13.49 7.86 95.82 3 0.124 0 0.000 0.124
この例の出力は、若い世代のコレクションが3番目と4番目のサンプル間で行われたことを示しています。コレクションには0.017秒かかっており、オブジェクトがeden領域(E)からOld領域(O)に昇格したため、old領域の使用率は46.56%から54.60%に増加しています。
-gcnew
オプションの使用例を次に示します。この例では、jstat
ユーティリティがLVMID番号2834に接続し、250ミリ秒間隔でサンプルを取り、出力を表示しています。さらに、-h3
オプションを使用して、データが3行表示されるごとに列ヘッダーを表示します。
$ jstat -gcnew -h3 2834 250
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
192.0 192.0 0.0 0.0 15 15 96.0 1984.0 942.0 218 1.999
192.0 192.0 0.0 0.0 15 15 96.0 1984.0 1024.8 218 1.999
192.0 192.0 0.0 0.0 15 15 96.0 1984.0 1068.1 218 1.999
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
192.0 192.0 0.0 0.0 15 15 96.0 1984.0 1109.0 218 1.999
192.0 192.0 0.0 103.2 1 15 96.0 1984.0 0.0 219 2.019
192.0 192.0 0.0 103.2 1 15 96.0 1984.0 71.6 219 2.019
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
192.0 192.0 0.0 103.2 1 15 96.0 1984.0 73.7 219 2.019
192.0 192.0 0.0 103.2 1 15 96.0 1984.0 78.0 219 2.019
192.0 192.0 0.0 103.2 1 15 96.0 1984.0 116.1 219 2.019
この例では、ヘッダー文字列の繰返しが見られるほかにも、4番目と5番目のサンプル間で若い世代のコレクションが発生し、その継続時間が0.02秒だったことがわかります。このコレクションでは、Survivor領域1の使用率(S1U)が適切なSurvivorサイズ(DSS)を超過するのに十分なライブ・データが検出されました。この結果、オブジェクトは、Old世代(この出力には非表示)へ昇格され、殿堂入りしきい値(TT)が、15から1へ降格されました。
-gcoldcapacity
オプションの使用例を次に示します。この例では、jstat
ユーティリティがLVMID番号21891に接続し、250ミリ秒間隔で3つのサンプルを取っています。-t
オプションを使用して、最初の列にサンプルごとのタイムスタンプを表示しています。
$ jstat -gcoldcapacity -t 21891 250 3
Timestamp OGCMN OGCMX OGC OC YGC FGC FGCT GCT
150.1 1408.0 60544.0 11696.0 11696.0 194 80 2.874 3.799
150.4 1408.0 60544.0 13820.0 13820.0 194 81 2.938 3.863
150.7 1408.0 60544.0 13820.0 13820.0 194 81 2.938 3.863
Timestamp列には、ターゲットJVMの起動時からの経過時間が、秒単位で報告されています。さらに、-gcoldcapacity
出力では、割当て要求または昇格要求あるいはその両方を満たすためにヒープが拡張するたびに、Old世代の容量(OGC)とOld領域の容量(OC)とが増加していることがわかります。OGCは、81番目の全世代の容量(FGC)後に、11696 KBから13820 KBへ増加しています。この世代(および領域)の最大容量は、60544 Kバイト(OGCMX)なので、まだ拡張できる余裕が残されています。
visualgc
ツールは、ガベージ・コレクション(GC)システムのグラフィカル表示を提供します。
visualgc
ツールは、jstat
ツールに関連があります。「jstatユーティリティ」を参照してください。visualgc
ツールは、ガベージ・コレクション(GC)システムのグラフィカル表示を提供します。これはjstat
と同様に、Java HotSpot VMの組込みインストゥルメンテーションを使用します。
visualgc
ツールはJDKリリースには含まれていませんが、jvmstat
テクノロジ・ページから個別のダウンロードとして入手できます。
図2-16は、GCおよびヒープの視覚化を示しています。
Oracle Solaris、Linux、Windowsなどのオペレーティング・システムのアプリケーション・コンソールで[Ctrl]キーとバックスラッシュ([\])キーを押したときの結果。
Oracle SolarisまたはLinuxオペレーティング・システムの場合、アプリケーション・コンソール(標準入力)で[Ctrl]キーとバックスラッシュ([\])キーの組合せを押すと、Java HotSpot VMからアプリケーションの標準出力にスレッド・ダンプが出力されます。Windowsの場合、同等のキー・シーケンスは[Ctrl]キーと[Break]キーです。これらのキーの組合せを表す一般的な用語は、Ctrl+Breakハンドラです。
Oracle SolarisおよびLinuxオペレーティング・システムでは、Javaプロセスがquitシグナルを受信するとスレッド・ダンプが出力されます。したがって、kill -QUIT pid
コマンドを実行すると、pid
をIDに持つプロセスから標準出力にスレッド・ダンプが出力されます。
次の項では、Ctrl+Breakハンドラによってトレースされるデータについて説明します。
スレッド・ダンプは、仮想マシン内のすべてのJavaスレッドのスレッド・スタック(スレッドの状態など)で構成されています。
スレッド・ダンプによってアプリケーションが終了することはなく、スレッド情報が出力された後もアプリケーションは続行します。
次の例はスレッド・ダンプを示しています。
Full thread dump Java HotSpot(TM) Client VM (1.6.0-rc-b100 mixed mode): "DestroyJavaVM" prio=10 tid=0x00030400 nid=0x2 waiting on condition [0x00000000..0xfe77fbf0] java.lang.Thread.State: RUNNABLE "Thread2" prio=10 tid=0x000d7c00 nid=0xb waiting for monitor entry [0xf36ff000..0xf36ff8c0] java.lang.Thread.State: BLOCKED (on object monitor) at Deadlock$DeadlockMakerThread.run(Deadlock.java:32) - waiting to lock <0xf819a938> (a java.lang.String) - locked <0xf819a970> (a java.lang.String) "Thread1" prio=10 tid=0x000d6c00 nid=0xa waiting for monitor entry [0xf37ff000..0xf37ffbc0] java.lang.Thread.State: BLOCKED (on object monitor) at Deadlock$DeadlockMakerThread.run(Deadlock.java:32) - waiting to lock <0xf819a970> (a java.lang.String) - locked <0xf819a938> (a java.lang.String) "Low Memory Detector" daemon prio=10 tid=0x000c7800 nid=0x8 runnable [0x00000000..0x00000000] java.lang.Thread.State: RUNNABLE "CompilerThread0" daemon prio=10 tid=0x000c5400 nid=0x7 waiting on condition [0x00000000..0x00000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" daemon prio=10 tid=0x000c4400 nid=0x6 waiting on condition [0x00000000..0x00000000] java.lang.Thread.State: RUNNABLE "Finalizer" daemon prio=10 tid=0x000b2800 nid=0x5 in Object.wait() [0xf3f7f000..0xf3f7f9c0] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0xf4000b40> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116) - locked <0xf4000b40> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159) "Reference Handler" daemon prio=10 tid=0x000ae000 nid=0x4 in Object.wait() [0xfe57f000..0xfe57f940] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0xf4000a40> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:485) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116) - locked <0xf4000a40> (a java.lang.ref.Reference$Lock) "VM Thread" prio=10 tid=0x000ab000 nid=0x3 runnable "VM Periodic Task Thread" prio=10 tid=0x000c8c00 nid=0x9 waiting on condition
この出力は、空白行で区切られたいくつかのスレッド・エントリで構成されます。Javaスレッド(Java言語コードを実行できるスレッド)がまず出力され、それらの後にVM内部スレッドに関する情報が続きます。各スレッド・エントリは、ヘッダー行とその後に続くスレッド・スタック・トレースで構成されます。
ヘッダー行には、スレッドに関する次の情報が含まれます。
スレッド名
スレッドがデーモン・スレッドかどうかのマーク
スレッド優先度(prio)
スレッドID (tid)。メモリー内のスレッド構造体のアドレスです
ネイティブ・スレッドのID (nid)
スレッド・ダンプ時にスレッドが実行していた内容を示す、スレッド状態詳細は、表2-6を参照してください。
アドレス範囲(スレッドのおおよその有効なスタック領域を表す)
Ctrl+Breakハンドラは、スレッドのデッドロック検出にも使用できます。
Ctrl+Breakハンドラは、スレッド・スタックだけでなく、デッドロック検出アルゴリズムも実行します。デッドロックが検出された場合、次の例に示すように、Ctrl+Breakハンドラは、デッドロックされた各スレッドに関するスレッド・ダンプの後に追加情報を出力します。
Found one Java-level deadlock: ============================= "Thread2": waiting to lock monitor 0x000af330 (object 0xf819a938, a java.lang.String), which is held by "Thread1" "Thread1": waiting to lock monitor 0x000af398 (object 0xf819a970, a java.lang.String), which is held by "Thread2" Java stack information for the threads listed above: =================================================== "Thread2": at Deadlock$DeadlockMakerThread.run(Deadlock.java:32) - waiting to lock <0xf819a938> (a java.lang.String) - locked <0xf819a970> (a java.lang.String) "Thread1": at Deadlock$DeadlockMakerThread.run(Deadlock.java:32) - waiting to lock <0xf819a970> (a java.lang.String) - locked <0xf819a938> (a java.lang.String) Found 1 deadlock.
JVMフラグ-XX:+PrintConcurrentLocks
が設定されている場合、Ctrl+Breakハンドラは各スレッドが所有している並行ロックのリストも出力します。
Ctrl+Breakハンドラはヒープ・サマリーの出力にも使用できます。
次の例では、様々な世代(ヒープ領域)がそのサイズ、使用量、アドレス範囲とともに示されています。アドレス範囲は特に、pmap
などのツールでプロセスを調査する場合にも役立ちます。
Heap def new generation total 1152K, used 435K [0x22960000, 0x22a90000, 0x22e40000 ) eden space 1088K, 40% used [0x22960000, 0x229ccd40, 0x22a70000) from space 64K, 0% used [0x22a70000, 0x22a70000, 0x22a80000) to space 64K, 0% used [0x22a80000, 0x22a80000, 0x22a90000) tenured generation total 13728K, used 6971K [0x22e40000, 0x23ba8000, 0x269600 00) the space 13728K, 50% used [0x22e40000, 0x2350ecb0, 0x2350ee00, 0x23ba8000) compacting perm gen total 12288K, used 1417K [0x26960000, 0x27560000, 0x2a9600 00) the space 12288K, 11% used [0x26960000, 0x26ac24f8, 0x26ac2600, 0x27560000) ro space 8192K, 62% used [0x2a960000, 0x2ae5ba98, 0x2ae5bc00, 0x2b160000) rw space 12288K, 52% used [0x2b160000, 0x2b79e410, 0x2b79e600, 0x2bd60000)
JVMフラグ-XX:+PrintClassHistogram
が設定されている場合、Ctrl+Breakハンドラはヒープ・ヒストグラムを生成します。
Windows、LinuxおよびOracle Solarisオペレーティング・システムで使用可能なネイティブ・ツールのうち、トラブルシューティングやモニタリングの目的で役立つもののリスト。
各ツールについて簡単な説明が提供されます。詳細は、オペレーティング・システムのマニュアル(またはOracle SolarisおよびLinuxオペレーティング・システムのマニュアル・ページ)を参照してください。
コマンド行ユーティリティからのログ・ファイルや出力の形式は、リリースごとに異なります。たとえば、致命的エラー・ログの形式に依存するスクリプトを開発した場合、そのログ・ファイルの形式が将来のリリースで変更されれば、同じスクリプトでも動作しなくなる可能性があります。
Windows固有のデバッグ・サポートは、MSDN Developer Networkで検索することもできます。
次の項では、いくつかのオペレーティング・システム・ツールのトラブルシューティング手法および改善について説明します。
Oracle Solaris 10オペレーティング・システムに含まれるDTraceツールを使用すれば、オペレーティング・システムのカーネルおよびユーザー・レベルのプログラムの動的トレースを行えます。
このツールでは、システム・コールの入口と出口、ユーザー・モード関数の入口と出口、およびその他多くのプローブ・ポイントでのスクリプトがサポートされます。スクリプトは、安全なポインタ・セマンティクスを備えた、Cに似た言語であるDプログラミング言語で記述されます。これらのスクリプトは、問題のトラブルシューティングやパフォーマンス問題の解決に役立つ可能性があります。
dtrace
コマンドは、DTraceツールに対する汎用のフロント・エンドです。このコマンドには、D言語を呼び出したり、バッファ内のトレース・データを取得したり、トレース・データを書式設定/出力するための一連の基本ルーチンにアクセスしたりするための、単純なインタフェースが用意されています。
カスタマイズされた独自のDTraceスクリプトをD言語で記述したり、すでに様々なサイト上で入手可能な多くのスクリプトから1つ以上をダウンロードして使用したりすることもできます。
これらのプローブは、プロバイダと呼ばれるカーネル・モジュールによって配布され計測されます。プローブ・プロバイダによって提供されるトレースのタイプには、ユーザー命令トレース、関数境界トレース、カーネル・ロック計測、プロファイル割込み、システム・コール・トレースなどがあり、その他にもたくさんあります。独自のスクリプトを記述する場合は、D言語を使用してそれらのプローブを有効にします。この言語では、条件付きトレースや出力のフォーマットも可能です。
dtrace -l
コマンドを使用すると、使用しているOracle Solarisオペレーティング・システムで使用可能な一連のプロバイダやプローブを調べることができます。
DTraceToolkitは、Oracle Solaris DTraceのオープン・コミュニティで開発されたドキュメント付きの有用なスクリプトを集めたものです。DTraceToolkitに関する項を参照してください。
Solaris動的トレース・ガイドを参照してください。
Java HotSpot VMにはhotspot
およびhotspot_jni
という2つの組込みプローブ・プロバイダが含まれるようになりました。
これらのプロバイダは、VMの内部状態やアクティビティだけでなく、実行中のJavaアプリケーションもモニターするために使用できるプローブを配布します。
JVMプローブ・プロバイダは次のように分類できます。
VMのライフ・サイクル: VMの初期化の開始と終了、およびVMのシャットダウン
スレッドのライフ・サイクル: スレッドの開始と停止、スレッド名、スレッドIDなど
クラスのロード: Javaクラスのロードとアンロード
ガベージ・コレクション: ガベージ・コレクションの開始と停止、システム全体またはメモリー・プール別
メソッドのコンパイル: メソッドのコンパイルの開始と終了、メソッドのロードとアンロード
モニター・プローブ: 待機イベント、通知イベント、競合するモニターへの出入り
アプリケーションの追跡: メソッドに入る、メソッドから戻る、Javaオブジェクトの割当て
ネイティブ・コードからJavaコードへの呼出しの場合、ネイティブ・コードはJNIインタフェース経由で呼出しを行う必要があります。hotspot_jni
プロバイダは、Javaコードを呼び出したりVMの状態を検査したりするためにJNIインタフェースに用意されているメソッドごとに、入口と出口におけるDTraceプローブを管理します。
プローブ・ポイントで現在のスレッドのスタック・トレースを出力するには、ustack組込み関数を使用できます。この関数は、C/C++ネイティブ関数の名前だけでなく、Javaメソッドの名前も出力します。次の例は、あるスレッドがreadシステム・コールを呼び出したときに必ず完全なスタック・トレースを出力する単純なDスクリプトです。
#!/usr/sbin/dtrace -s syscall::read:entry /pid == $1 && tid == 1/ { ustack(50, 0x2000); }
前の例のスクリプトはread.d
というファイルに格納され、次の例に示すように、トレース対象のJavaプロセスのPIDを指定することで実行されます。
read.d pid
Javaアプリケーションで多数のI/Oが生成されたり、なんらかの予期しない遅延が発生したりした場合、DTraceツールやそのustack()アクションを使用すれば、問題を診断しやすくなる可能性があります。
Oracle Solaris 10オペレーティング・システムのpmap
ユーティリティの改善。
pmap
ユーティリティは、Oracle Solaris 10オペレーティング・システムでスタック・セグメントがテキスト[stack]
付きで出力されるように改善されました。このテキストはスタックの場所を見つけるのに役立ちます。
次の例は、改善されたpmap
ユーティリティによるスタック・トレースを示しています。
19846: /net/myserver/export1/user/j2sdk6/bin/java -Djava.endorsed.d 00010000 72K r-x-- /export/disk09/jdk/6/rc/b63/binaries/solsparc/bin/java 00030000 16K rwx-- /export/disk09/jdk/6/rc/b63/binaries/solsparc/bin/java 00034000 32544K rwx-- [ heap ] D1378000 32K rwx-R [ stack tid=44 ] D1478000 32K rwx-R [ stack tid=43 ] D1578000 32K rwx-R [ stack tid=42 ] D1678000 32K rwx-R [ stack tid=41 ] D1778000 32K rwx-R [ stack tid=40 ] D1878000 32K rwx-R [ stack tid=39 ] D1974000 48K rwx-R [ stack tid=38 ] D1A78000 32K rwx-R [ stack tid=37 ] D1B78000 32K rwx-R [ stack tid=36 ] [.. more lines removed here to reduce output ..] FF370000 8K r-x-- /usr/lib/libsched.so.1 FF380000 8K r-x-- /platform/sun4u-us3/lib/libc_psr.so.1 FF390000 16K r-x-- /lib/libthread.so.1 FF3A4000 8K rwx-- /lib/libthread.so.1 FF3B0000 8K r-x-- /lib/libdl.so.1 FF3C0000 168K r-x-- /lib/ld.so.1 FF3F8000 8K rwx-- /lib/ld.so.1 FF3FA000 8K rwx-- /lib/ld.so.1 FFB80000 24K ----- [ anon ] FFBF0000 64K rwx-- [ stack ] total 167224K
Oracle Solaris 10オペレーティング・システムのpstack
ユーティリティの改善。
Oracle Solaris 10オペレーティング・システムより前は、pstack
ユーティリティはJavaをサポートしていませんでした。解釈済みおよびコンパイル済みJavaメソッドの両方で、16進アドレスを出力していました。
Oracle Solaris 10オペレーティング・システム以降のpstack
コマンド行ツールは、コア・ファイルまたはライブ・プロセスから混合モードのスタック・トレース(JavaおよびC/C++フレーム)を出力します。このユーティリティは、解釈済、コンパイル済、およびインライン化されたJavaメソッドに対し、Javaメソッド名を出力します。
JDKには、JREに配備されているアプリケーションの問題を観察、モニター、プロファイル、デバッグ、および診断するカスタム・ツールを開発するための広範なAPIが含まれています。
新しいツールの開発はこのドキュメントの対象外です。かわりにこのセクションでは、使用可能なAPIの概要を簡単に説明します。
この項に示されたすべてのパッケージは、Java SE API仕様で説明されています。
JDKダウンロードに含まれるコード例やデモ・コードを参照してください。
次の項では、トラブルシューティングのためのカスタム診断ツールとして使用できるパッケージ、インタフェース・クラスおよびJavaデバッガについて説明します。
Java Platform Debugger Architecture (JPDA)は、デバッガやデバッガに似たツールが使用するために設計されたアーキテクチャです。
Java Platform Debugger Architectureは、2つのプログラミング・インタフェースおよびワイヤ・プロトコルで構成されています。
Java Virtual Machine Tool Interface (JVM TI)は、仮想マシンへのインタフェースです。「JVM Tool Interface」を参照してください。
Java Debug Interface (JDI)は、ユーザー・コード・レベルでの情報および要求を定義します。これは、Javaプログラミング言語アプリケーションをデバッグするためのPure Javaプログラミング言語インタフェースです。JPDAでは、JDIは、デバッガのプロセスから見たデバッグ対象プロセスの仮想マシンのリモート・ビューです。これはフロント・エンドによって実装されます。デバッガに似たアプリケーション(IDE、デバッガ、トレーサ、モニタリング・ツールなど)はクライアントとなります。モジュールjdk.jdiを参照してください。
Java Debug Wire Protocol (JDWP)は、デバッグされるプロセスと、JDIを実装したデバッガ・フロント・エンドとの間で転送される、情報および要求の形式を定義します。
jdb
ユーティリティは、コマンド行デバッガの例としてJDKに含まれています。jdb
ユーティリティは、JDIを使ってターゲットVMを起動または接続します。「jdbユーティリティ」を参照してください。
JDIを使用すれば、従来のデバッガ・タイプのツールだけでなく、ポストモーテム診断の際や、ツールが非協力的なプロセス(ハングアップ・プロセスなど)に接続する必要があるシナリオで役に立つツールを開発することもできます。
NMTで使用されるネイティブ・メモリー・トラッキングのメモリー・カテゴリのリスト。
表2-1に、NMTで使用されるネイティブ・メモリー・カテゴリを示します。これらのカテゴリは、リリースにより変更される可能性があります。
表2-1 ネイティブ・メモリー・トラッキングのメモリー・カテゴリ
カテゴリ | 説明 |
---|---|
Javaヒープ |
オブジェクトが存在するヒープ |
クラス |
クラス・メタデータ |
コード |
生成されたコード |
GC |
カード表など、GCにより使用されるデータ |
コンパイラ |
コードを生成するときにコンパイラによって使用されるメモリー・トラッキング |
記号 |
記号 |
メモリー・トラッキング |
NMTによって使用されるメモリー。 |
空きチャンク・プール |
アリーナのチャンク・プール内のチャンクによって使用されるメモリー |
クラスの共有領域 |
クラス・データ共有アーカイブにマップされるメモリー |
スレッド |
スレッド・データ構造、リソース領域、ハンドル領域などを含む、スレッドによって使用されるメモリー。 |
スレッド・スタック |
スレッド・スタック。コミットされたメモリーとしてマークされますが、OSによって完全にコミットされない場合があります |
内部 |
コマンドライン・パーサー、JVMTI、プロパティおよびその他によって使用されるメモリーなど、前述のカテゴリに該当しないメモリー。 |
不明 |
メモリーのカテゴリを決定できない場合。 アリーナ: スタックまたは値オブジェクトとしてアリーナが使用されている場合 仮想メモリー: タイプ情報がまだ到着していない場合 |
アプリケーションとJava HotSpot VMとの間で発生する問題のポストモーテム診断用に使用可能なツールとオプションのリスト。
表2-2に、ポストモーテム診断用に設計されたオプションおよびツールの要約を示します。アプリケーションがクラッシュした場合、これらのオプションやツールを使用して、クラッシュ発生時、または後でクラッシュ・ダンプからの情報を使用して追加情報を取得できます。
表2-2 ポストモーテム診断ツール
ツールまたはオプション | 説明および使用方法 |
---|---|
致命的エラー・ログ |
回復不能(致命的)なエラーが発生すると、エラー・ログが作成されます。このファイルには、致命的エラーの発生時に取得された情報が含まれています。これは多くの場合、クラッシュ発生時に最初に調べる必要がある項目です。「致命的エラー・ログ」を参照してください。 |
|
このコマンド行オプションは、VMでネイティブのメモリー不足エラーが検出された際にヒープ・ダンプを生成することを指定します。「-XX:HeapDumpOnOutOfMemoryErrorオプション」を参照してください。 |
|
このコマンド行オプションは、致命的エラーの発生時にユーザー指定の一連のスクリプトまたはコマンドを実行することを指定します。たとえばWindowsの場合、このオプションでクラッシュ・ダンプを強制するコマンドを実行できます。ポストモーテム・デバッガが構成されていないシステムでは、このオプションが非常に役立ちます。「-XX:OnErrorオプション」を参照してください。 |
|
このコマンド行オプションは、致命的エラーの発生時にプロセスを中断します。このオプションはユーザーの応答に応じて、ネイティブ・デバッガ( |
その他の |
トラブルシューティングに役立つ |
|
デバッガ・サポートには、 |
(Oracle SolarisおよびLinuxオペレーティング・システムでのみ使用されるポストモーテム) |
このユーティリティは、クラッシュから取得されたコア・ファイル、または |
(Oracle SolarisおよびLinuxオペレーティング・システムでのみ使用されるポストモーテム) |
このユーティリティは、クラッシュから取得されたコア・ファイルから、または |
(Oracle SolarisおよびLinuxオペレーティング・システムのみ) |
Serviceability Agent Debug Daemon ( |
|
このユーティリティは、JavaプロセスからJavaおよびネイティブ・スタックの情報を取得できます。Oracle SolarisおよびLinuxオペレーティング・システムでは、コア・ファイルまたはリモート・デバッグ・サーバーからも情報を取得できます。「jstackユーティリティ」を参照してください。 |
ネイティブ・ツール |
各オペレーティング・システムには、ポストモーテム診断に使用可能なネイティブ・ツールおよびユーティリティがあります。「オペレーティング・システムのネイティブ・ツール」を参照してください。 |
ハングアップ・プロセスでアプリケーションとJava HotSpot VMとの間で発生する問題を診断するためのツールとオプションのリスト。
表2-3では、ハングアップまたはデッドロックしたプロセスに関連するシナリオで役立つ可能性のあるオプションやツールをまとめています。これらのツールでは、アプリケーション起動時に特殊なオプションは必要ありません。
JVMおよびJavaアプリケーションに関する問題を診断するには、Java Mission Control、Java Flight Recorderおよびjcmd
ユーティリティを使用できます。診断機能を強化し、パフォーマンスのオーバーヘッドを削減するには、以前のjstack
,、jinfo
およびjmap
ユーティリティのかわりに最新の診断ツールjcmd
の使用をお薦めします。
表2-3 ハングアップ・プロセス・ツール
ツールまたはオプション | 説明および使用方法 |
---|---|
Ctrl+Breakハンドラ (Oracle SolarisおよびLinuxオペレーティング・システムでは[Ctrl]+[\]または |
このキーの組合せでは、スレッド・ダンプとデッドロック検出が実行されます。Ctrl+Breakハンドラではオプションで、並行ロックとその所有者の一覧や、ヒープ・ヒストグラムを出力することもできます。「Ctrl+Breakハンドラ」を参照してください。 |
|
このユーティリティを使用してJVMに診断コマンド・リクエストを送信し、JVMではこれらのリクエストを使用してJavaフライト記録(JFR)を制御します。JFRはフライト記録のイベントのトラブルシューティングと診断に使用します。「jcmdユーティリティ」を参照してください。 |
|
デバッガ・サポートには、 |
|
このユーティリティはJavaプロセスから構成情報を取得できます。「jinfoユーティリティ」を参照してください。 |
|
このユーティリティは、Javaプロセスからヒープ・ヒストグラムなどのメモリー・マップ情報を取得できます。Oracle SolarisおよびLinuxオペレーティング・システムでは、プロセスがハングアップした場合に |
(Oracle SolarisおよびLinuxオペレーティング・システムのみ) |
Serviceability Agent Debug Daemon ( |
|
このユーティリティは、JavaプロセスからJavaおよびネイティブ・スタックの情報を取得できます。「jstackユーティリティ」を参照してください。 |
ネイティブ・ツール |
各オペレーティング・システムには、ハング・アップやデッドロックの状況で役立つ可能性のあるネイティブ・ツールおよびユーティリティがあります。「オペレーティング・システムのネイティブ・ツール」を参照してください。 |
実行中のアプリケーションをモニターして問題を検知するためのツールおよびオプションのリスト。
表2-4に示すツールは、実行中のアプリケーションのモニター用に設計されています。
JVMおよびJavaアプリケーションに関する問題を診断するには、Java Mission Control、Java Flight Recorderおよびjcmd
ユーティリティを使用できます。診断機能を強化し、パフォーマンスのオーバーヘッドを削減するには、以前のjstack
,、jinfo
およびjmap
ユーティリティのかわりに最新の診断ツールjcmd
の使用をお薦めします。
表2-4 モニタリング・ツール
ツールまたはオプション | 説明および使用方法 |
---|---|
Java Mission Control |
Java Mission Control (JMC)は、HotSpot JVM用の新しいJDKプロファイリングおよび診断ツール・プラットフォームです。基本的なモニタリングと管理、および本番稼働時のプロファイリングと診断を行う高性能なツール・スイートです。Java Mission Controlは、プロファイリング・ツールにつきもののパフォーマンス・オーバーヘッドの問題を最小限に抑えます。 |
|
このユーティリティを使用してJVMに診断コマンド・リクエストを送信し、JVMではこれらのリクエストを使用してJavaフライト記録を制御します。JFRは、フライト記録のイベントを使用してJVMおよびJavaアプリケーションのトラブルシューティングと診断に使用されます。「jcmdユーティリティ」を参照してください。 |
JConsoleユーティリティ |
このユーティリティは、Java Management Extensions (JMX)に基づくモニタリング・ツールです。このツールは、Java仮想マシンの組込みJMXインストゥルメンテーションを使用して、実行中のアプリケーションのパフォーマンスやリソース消費に関する情報を提供します。「JConsole」を参照してください。 |
|
このユーティリティは、Javaプロセス、コア・ファイル、またはリモート・デバッグ・サーバーから、ヒープ・ヒストグラムなどのメモリー・マップ情報を取得できます。「jmapユーティリティ」を参照してください。 |
|
このユーティリティは、ターゲット・システム上で計測されたJava HotSpot VMを一覧表示します。VMが埋め込まれた環境、つまり |
|
このユーティリティは、JavaプロセスからJavaおよびネイティブ・スタックの情報を取得できます。Oracle SolarisおよびLinuxオペレーティング・システムでは、コア・ファイルまたはリモート・デバッグ・サーバーからも情報を取得できます。「jstackユーティリティ」を参照してください。 |
|
このユーティリティは、Javaの組込みインストゥルメンテーションを使用して、実行中アプリケーションのパフォーマンスやリソース消費に関する情報を提供します。このツールは、パフォーマンスの問題、特にヒープ・サイズ決定やガベージ・コレクションに関係する問題を診断するときに使用できます。「jstatユーティリティ」を参照してください。 |
|
このユーティリティは、計測されたJava仮想マシンの作成と終了をモニターし、ローカル・ホスト上で実行されているVMにリモート・モニタリング・ツールが接続することを許可するインタフェースを提供する、Remote Method Invocation (RMI)サーバー・アプリケーションです。「jstatdデーモン」を参照してください。 |
|
このユーティリティは、ガベージ・コレクション・システムのグラフィカル表示を提供します。これは |
ネイティブ・ツール |
各オペレーティング・システムには、モニタリング目的に役立つ可能性のあるネイティブ・ツールおよびユーティリティがあります。たとえば、Oracle Solaris 10オペレーティング・システムで導入された動的トレース(DTrace)機能は、高度なモニタリングを実行します。「オペレーティング・システムのネイティブ・ツール」を参照してください。 |
問題の診断に役立つ一般的なトラブルシューティングのツール、オプション、変数およびプロパティのリスト。
特定タイプの問題向けに設計されたツールに加え、表2-5に示すツール、オプション、変数、およびプロパティは、その他の問題を診断するのに役立ちます。
JVMおよびJavaアプリケーションに関する問題を診断するには、Java Mission Control、Java Flight Recorderおよびjcmd
ユーティリティを使用できます。診断機能を強化し、パフォーマンスのオーバーヘッドを削減するには、以前のjstack
,、jinfo
およびjmap
ユーティリティのかわりに最新の診断ツールjcmd
の使用をお薦めします。
表2-5 一般的なトラブルシューティング・ツールおよびオプション
ツールまたはオプション | 説明および使用方法 |
---|---|
Java Mission Control |
Java Mission Control (JMC)は、HotSpot JVM用の新しいJDKプロファイリングおよび診断ツール・プラットフォームです。基本的なモニタリングと管理、および本番稼働時のプロファイリングと診断を行う高性能なツール・スイートです。Java Mission Controlは、プロファイリング・ツールにつきもののパフォーマンス・オーバーヘッドの問題を最小限に抑えます。「Java Mission Control」を参照してください。 |
|
このユーティリティを使用してJVMに診断コマンド・リクエストを送信し、JVMではこれらのリクエストを使用してJavaフライト記録(JFR)を制御します。JFRは、フライト記録のイベントを使用してJVMおよびJavaアプリケーションのトラブルシューティングと診断に使用されます。 |
|
このユーティリティは、指定されたJavaプロセスの特定のJVMフラグの値を動的に設定、設定解除および変更できます。Oracle SolarisおよびLinuxオペレーティング・システムでは、構成情報も出力できます。 |
|
このユーティリティはコマンド行スクリプト・シェルで、インタラクティブおよびバッチ・モードの両方のスクリプト実行をサポートしています。 |
Oracle Solaris Studio |
これはインタラクティブなコマンド行デバッグ・ツールで、プログラムを停止してその状態を調べるなど、プログラムの動的実行を完全に制御できます。詳細は、Oracle Solaris Studioプログラム・デバッギングにある |
Oracle Solaris Studioパフォーマンス・アナライザ |
このツールを使って、コードのパフォーマンスを評価し、潜在的なパフォーマンス問題を特定し、コード内で問題が発生する部分を突きとめることが容易になる可能性があります。Performance Analyzerはコマンド行、またはグラフィカル・ユーザー・インタフェースから使用できます。詳細は、Oracle Solaris Studioパフォーマンス・アナライザを参照してください。 |
Sunのデータ領域プロファイリング: DProfile |
このツールは、Sunコンピューティング・システム内でのデータ・フローを洞察することで、ソフトウェアとハードウェアの両方のボトルネックを特定するのを支援します。DProfileは、Sun Studio 11コンパイラ・スイートでPerformance Analyzer GUI経由でサポートされています。DTraceまたは動的トレース診断ツールに関する項を参照してください。 |
|
このオプションは、Java Native Interface (JNI)を使用する、またはサード・パーティのライブラリ(一部のJDBCドライバなど)を採用するアプリケーションの問題を診断する際に役立ちます。「-Xcheck:jniオプション」を参照してください。 |
|
このオプションは、クラスのロードとアンロードのロギングを有効にします。「-verbose:classオプション」を参照してください。 |
|
このオプションは、ガベージ・コレクション情報のロギングを有効にします。「-verbose:gcオプション」を参照してください。 |
|
このオプションは、JNIのロギングを有効にします。「-verbose:jniオプション」を参照してください。 |
|
この環境変数では、ツールの初期化(具体的には |
|
このシステム・プロパティは、JavaのJREのセキュリティ・チェックが実行中にトレース・メッセージを出力するかどうかを制御します。「java.security.debugシステム・プロパティ」を参照してください。 |
java.lang.management
パッケージは、JVMやオペレーティング・システムをモニターおよび管理するための管理インタフェースを提供します。
具体的には、次の各システムのインタフェースがカバーされています。
クラスのロード
コンパイル
ガベージ・コレクション
メモリー・マネージャ
ランタイム
スレッド
JDKには、java.lang.management
パッケージの使用方法を示すコード例が含まれています。これらの例は$JAVA_HOME/demo/managemen
ディレクトリにあります。コード例の一部を次に示します。
MemoryMonitor
は、java.lang.management
APIを使ってアプリケーションで消費されるすべてのメモリー・プールのメモリー使用量をモニターする方法を示します。
FullThreadDump
は、java.lang.management
APIを使って完全なスレッド・ダンプを取得し、プログラムでデッドロックを検出する方法を示します。
VerboseGC
は、java.lang.management
APIを使ってアプリケーションのガベージ・コレクション統計やメモリー使用量を出力する方法を示します。
JDKリリースにはjava.lang.management
パッケージのほかに、プラットフォーム拡張がcom.sun.management
パッケージとして含まれています。プラットフォーム拡張には、コレクションをサイクルで実行するガベージ・コレクタから詳細統計を取得するための管理インタフェースが含まれています。これらの拡張には、オペレーティング・システムから追加のメモリー統計を取得するための管理インタフェースも含まれています。
java.lang.instrument
パッケージは、Javaプログラミング言語エージェントがJVMで実行中のプログラムを計測することを許可するサービスを提供します。
インストゥルメンテーションは、プロファイラなどのツールや、メソッド呼出しをトレースするためのツールなどで使用されます。このパッケージを使えば、ロード時および動的計測の両方が容易になります。また、ロード済クラスに関する情報や特定のオブジェクトが消費するストレージ量に関する情報を取得するメソッドも含まれています。
java.lang.Thread
クラスには、すべてのライブ・メソッドのスタック・トレースのマップを返す、getAllStackTracesと呼ばれるstaticメソッドが含まれています。
Thread
クラスには、スレッドの状態を返す、getStateと呼ばれるメソッドも含まれています。スレッドの状態はjava.lang.Thread.State
列挙型で定義されます。これらのメソッドは、診断またはモニタリング機能をアプリケーションに追加する際に役立つことがあります。
JVM Tools Interface (JVM TI)とは、様々な開発ツールやモニタリング・ツールで使用できるネイティブ(C/C++)プログラミング・インタフェースです。
JVM TIは、VMの状態にアクセスする必要のある各種ツール(プロファイリング・ツール、デバッグ・ツール、モニタリング・ツール、スレッド分析ツール、カバレージ分析ツールを含むがこれに限らない)のためのインタフェースを提供します。
JVM TIに依存するエージェントのいくつかの例を次に示します。
Java Debug Wire Protocol (JDWP)
java.lang.instrument
パッケージ
JVM TIの仕様は、JVM Tool Interfaceのドキュメントで参照できます。
JDKには、JVM TIの使用方法を示すコード例が含まれています。これらの例は$JAVA_HOME/demo/jvmti
ディレクトリにあります。コード例の一部を次に示します。
mtrace
は、メソッドの呼出しおよび復帰回数を追跡するエージェント・ライブラリです。これは、バイトコード・インストゥルメンテーションを使って仮想マシンにロードされたすべてのクラスを計測し、使用頻度の高いメソッドのソート済みリストを出力します。
heapTracker
は、オブジェクトの割当てを追跡するエージェント・ライブラリです。これは、バイトコード・インストゥルメンテーションを使ってコンストラクタ・メソッドを計測します。
heapViewer
は、Ctrl+Breakハンドラが呼び出されたときにヒープ統計を出力するエージェント・ライブラリです。「Ctrl+Breakハンドラ」を参照してください。ロードされたクラスごとに、そのクラスのインスタンス数と使用済容量を出力します。
jrunscript
ユーティリティはコマンド行スクリプト・シェルです。
インタラクティブ・モード、バッチ・モードの両方のスクリプト実行がサポートされています。このシェルではデフォルトでJavaScriptが使用されますが、他の任意のスクリプト言語を指定することもできます。そのためには、そのスクリプト・エンジンの.class
ファイルを含むJARファイルへのパスを指定します。
jrunscript
ユーティリティは、Java言語とスクリプト言語との通信によって探求的なプログラミング・スタイルをサポートしています。
Javaサービスアビリティ・エージェント・デバッグ・デーモン(jsadebugd
)は、Javaプロセスまたはコア・ファイルに接続し、デバッグ・サーバーとして動作します。
このユーティリティは現在のところ、Oracle SolarisおよびLinuxオペレーティング・システムでのみ利用できます。jstack
、jmap
およびjinfo
などのリモート・クライアントは、Java Remote Method Invocation (RMI)を使用しているサーバーに接続できます。
jstatd
デーモンは、計測された各Java HotSpotの作成と終了をモニターし、ローカル・ホスト上で実行されているJVMにリモート・モニタリング・ツールが接続できるようにするインタフェースを提供する、RMIサーバー・アプリケーションです。
たとえば、このデーモンを使えば、jps
ユーティリティでリモート・システム上のプロセスを一覧表示できます。
注意:
FAT32ファイル・システム上では、インストゥルメンテーションにアクセスできません。
スレッド・ダンプに表示される可能性があるスレッド状態のリスト。
表2-6は、Ctrl+Breakハンドラによるスレッド・ダンプで可能なスレッド状態を示しています。
表2-6 スレッド・ダンプのスレッド状態
スレッド状態 | 説明 |
---|---|
NEW |
スレッドはまだ開始されていません。 |
RUNNABLE |
スレッドはJVM内で実行されています。 |
BLOCKED |
スレッドはモニター・ロックを待機してブロックされています。 |
WAITING |
スレッドは、別のスレッドが特定のアクションを実行するのを無期限に待機しています。 |
TIMED_WAITING |
スレッドは指定された待機時間、別のスレッドがアクションを実行するのを待機しています。 |
TERMINATED |
スレッドは終了しています。 |
問題のトラブルシューティングに利用できるWindowsのネイティブ・ツールのリスト。
表2-7は、Windowsオペレーティング・システムで使用可能なトラブルシューティング・ツールの一覧を示しています。
表2-7 Windowsのネイティブ・トラブルシューティング・ツール
ツール | 説明 |
---|---|
|
メモリー・ダンプ・ファイルが正常に作成されたことを確認するコマンド行ユーティリティ。このツールは、MicrosoftのWebサイトから入手可能なDebugging Tools for Windowsダウンロードに含まれています。「Windowsでのクラッシュ・ダンプの収集」を参照してください。 |
|
Visual C++およびWin32デバッガの起動に使用可能なコマンド行ユーティリティ。 |
|
User Mode Process Dumperは、MicrosoftのWebサイトから入手可能なOEM Support Toolsダウンロードに含まれています。「Windowsでのクラッシュ・ダンプの収集」を参照してください。 |
|
Windowsデバッガは、Windowsアプリケーションまたはクラッシュ・ダンプのデバッグに使用できます。このツールは、MicrosoftのWebサイトから入手可能なDebugging Tools for Windowsダウンロードに含まれています。「Windowsでのクラッシュ・ダンプの収集」を参照してください。 |
|
メモリー割当てを追跡するための追加サポートを自動的に含めるコンパイラ・オプション。 |
表2-8では、Linuxオペレーティング・システム・バージョン10で導入または改善されたいくつかのトラブルシューティング・ツールについて説明しています。
表2-8 Linuxのネイティブ・トラブルシューティング・ツール
ツール | 説明 |
---|---|
|
C++分解シンボル名を分解解除します。このユーティリティは、Linux上の |
|
GNUデバッガ |
|
メモリー割当ての追跡 |
|
スレッド・スタックを出力します(Oracle Solarisオペレーティング・システムの すべてのディストリビューションがデフォルトでこのツールを提供しているわけではありません。したがって、オープン・ソース・ダウンロードからのダウンロードが必要になる場合があります。 |
|
ライブラリ呼出しトレーサ(Oracle Solarisオペレーティング・システムの すべてのディストリビューションがデフォルトでこのツールを提供しているわけではありません。したがって、オープン・ソース・ダウンロードからのダウンロードが必要になる場合があります。 |
|
GNU |
|
Oracle Solarisオペレーティング・システムの |
|
システム・コール・トレーサ(Oracle Solarisオペレーティング・システムの |
|
CPU負荷が非常に高いプロセスを表示します。 |
|
プロセス、メモリー、ページング、ブロックI/O、トラップ、およびCPUアクティビティに関する情報を報告します。 |
表2-9は、Oracle Solarisオペレーティング・システムで使用可能なトラブルシューティング・ツールの一覧を示しています。
表2-9 Oracle Solarisオペレーティング・システムのネイティブ・トラブルシューティング・ツール
ツール | 説明 |
---|---|
|
JVMによって生成されるコア・ファイルの名前と場所を指定します。 |
|
CPUパフォーマンス・カウンタを使ってシステム動作をモニターします。 |
|
CPUパフォーマンス・カウンタを使用してプロセスとLWPの動作をモニターします。 |
|
C++分解シンボル名を分解解除します。このユーティリティは、Oracle Solarisオペレーティング・システム上の |
|
DTraceは、Oracle Solaris 10オペレーティング・システムで導入された、動的トレース・コンパイラおよびトレース・ユーティリティです。これは、カーネル関数、システム・コール、およびユーザー関数の動的トレースを実行できます。このツールを使えば、入口、出口、およびその他のプローブ・ポイントで任意の安全なスクリプトを実行できます。スクリプトは、Dプログラミング言語と呼ばれる、Cに似ているが安全なポインタ・セマンティクス言語で記述されます。「DTraceツール」も参照してください。 |
|
プロセスのコア・ダンプを強制します。コア・ダンプの書込み後、プロセスは継続します。 |
|
割込みスレッドで消費されるCPUに関する統計を報告します。 |
|
I/O統計を報告します。 |
|
このライブラリは、Oracle Solaris 9オペレーティング・システムupdate 3で導入され、高速かつスケーラブルなオブジェクト・キャッシュ用メモリー割当ておよび拡張デバッグ・サポートを提供します。このツールでは、メモリー管理のバグを検出して修正できます。「libumemツールによるリークの検出」を参照してください。 |
|
カーネルおよびユーザー・アプリケーションとクラッシュ・ダンプ用のモジュラ・デバッガ |
|
各種ネットワーク関連データ構造体の内容を表示します。 |
|
プロセス引数、環境変数または補助ベクトルを出力します。ほかのコマンド( |
|
プロセス・ファイル記述子に関する情報を出力します。Oracle Solaris 10オペレーティング・システム以降、ファイル名も出力されるようになりました。 |
|
プロセスによってロードされた共有オブジェクトを出力します。 |
|
プロセスまたはコア・ファイルのメモリー・レイアウト(ヒープ、データおよびテキスト・セクションを含む)を出力します。Oracle Solaris 10以降は、スタック・セグメントがテキスト |
|
アクティブなOracle Solarisオペレーティング・システム・プロセスの統計を報告します。( |
|
プロセスを実行モードに設定します( |
|
すべてのプロセスを一覧表示します。 |
|
プロセスのシグナル・ハンドラを一覧表示します。 |
|
特定のプロセスまたはコア・ファイルのスレッドのスタックを出力します。Oracle Solaris 10オペレーティング・システム以降は、JavaフレームでJavaメソッド名を出力できます。「pstackユーティリティの改善」を参照してください。 |
|
プロセスを停止(中断)します。 |
|
指定されたPIDを含むプロセス・ツリーを出力します。 |
|
システム・アクティビティ・レポータ |
|
CPU負荷が非常に高いプロセスを表示します( |
|
システム・パフォーマンス(CPU、ディスク、ネットワークなど)を示すグラフを表示します。 |
|
CPU負荷が非常に高いプロセスを表示します。このツールは、Oracle Solarisオペレーティング・システムではフリーウェアとして利用可能ですが、デフォルトではインストールされません。 |
|
実行時トラップ統計(SPARCのみ)を表示します。 |
|
システム・コール、ユーザー・モード関数、およびシグナルの入口および出口イベントをトレースし、オプションでこれらのイベントのいずれかでプロセスを停止します。このツールは、システム・コールやユーザー関数の引数も出力します。 |
|
システム仮想メモリーの統計を報告します。 |
|
メモリー割当てを追跡します。 |