3 JConsoleの使用

JConsoleグラフィカル・ユーザー・インタフェースは、Java Management Extensions (JMX)仕様に準拠したモニタリング・ツールです。JConsoleはJava仮想マシン(Java VM)の広範なインストゥルメンテーションを使用して、Javaプラットフォームで実行されるアプリケーションのパフォーマンスとリソース消費に関する情報を提供します。

JConsoleが更新され、WindowsおよびGNOMEデスクトップのルック・アンド・フィールが提供されるようになりました(その他のプラットフォームでは標準的なJavaのグラフィカル・ルック・アンド・フィールが提供されます)。このドキュメントに掲載した画面キャプチャは、Windows XPで動作するインタフェースのインスタンスから取得されました。

JConsoleの起動

jconsole実行可能ファイルは、JDK_HOME/binにあります。ここでJDK_HOMEは、Java Development Kit (JDK)がインストールされているディレクトリです。このディレクトリがシステム・パスにある場合は、コマンド(シェル)プロンプトでjconsoleと入力するだけで、JConsoleを起動できます。それ以外の場合は、実行可能ファイルへのフル・パスを入力する必要があります。

コマンド構文

JConsoleを使用すれば、ローカル・アプリケーション(JConsoleと同じシステム上で動作するアプリケーション)とリモート・アプリケーション(ほかのシステム上で動作するアプリケーション)の両方をモニターできます。

注意:

JConsoleを使用してローカル・アプリケーションをモニターするのは、開発やプロトタイプ作成には便利ですが、JConsole自体がかなりのシステム・リソースを消費するため、実稼動環境で使用することはお薦めしません。JConsoleアプリケーションをモニタリング対象のプラットフォームから切り離すために、リモート・モニタリングをお薦めします。

完全な構文は、Java Development Kitツール仕様jconsoleに関する項を参照してください。

ローカル・モニタリングの設定

次のコマンドを使用してJConsoleを起動します。

% jconsole

JConsoleが起動したら、JConsoleが接続可能なロカールで実行しているJavaアプリケーションのうち、必要なものを選択します。

特定のアプリケーションをモニターする場合、そのアプリケーションのプロセスIDがわかっていれば、JConsoleを起動して、そのアプリケーションに接続できます。この場合、アプリケーションはJConsoleと同じユーザーIDで実行する必要があります。次のコマンド構文を使用して、特定アプリケーションのローカル・モニタリングのためにJConsoleを起動します。

% jconsole processID

processIDは、アプリケーションのプロセスID (PID)です。アプリケーションのPIDを調べるには、次の手順を実行します。

  • LinuxまたはmacOSシステムの場合、psコマンドを使用して、実行中のjavaインスタンスのPIDを見つけることができます。

  • Windowsシステムの場合、タスク・マネージャを使用して、javaまたはjavawのPIDを見つけます。

  • jpsコマンド行ユーティリティを使用してPIDを調べることもできます。Java Development Kitツール仕様jpsに関する項を参照してください。

たとえば、NotepadアプリケーションのプロセスIDが2956である場合は、次のコマンドでJConsoleを起動します。

% jconsole 2956

JConsoleとアプリケーションは同じユーザーが実行する必要があります。管理およびモニタリング・システムは、オペレーティング・システムのファイル・アクセス権を使用します。プロセスIDを指定しない場合、JConsoleによってローカルのJavaアプリケーションがすべて自動的に検出され、モニターするアプリケーションを選択するためのダイアログ・ボックスが表示されます(「JMXエージェントへの接続」を参照)。

ローカル・モニタリングおよび管理を参照してください。

リモート・モニタリングの設定

リモート・モニタリングのためにJConsoleを起動するには、次のコマンド構文を使用します。

% jconsole hostName:portNum

hostNameはアプリケーションを実行するシステムの名前、portNumは、Java VMを起動してJMXエージェントを有効にしたときに指定したポート番号です。リモート・モニタリングおよび管理を参照してください。

ホスト名/ポート番号の組み合わせを指定しない場合、JConsoleには、ホスト名とポート番号が入力可能な接続ダイアログ・ボックス(JMXエージェントへの接続)が表示されます。

セキュアなリモート・モニタリングの設定

Secure Sockets Layer (SSL)でセキュリティ保護された接続によりモニタリングを実行するよう、JConsoleを起動することもできます。セキュアな接続を使用してJConsoleを起動するコマンドは、JConsoleによるリモート・モニタリング(SSLが有効な場合)を参照してください。

JMXエージェントへの接続

接続先のJMXエージェントを指定する引数を使用してJConsoleを起動した場合、指定したJava VMのモニタリングが自動的に開始されます。「接続」「新規接続」|を選択し、必要な情報を入力することで、いつでも別のホストに接続できます。

JConsoleを起動するときに引数を指定しない場合、最初に接続ダイアログ・ボックスが表示されます。このダイアログ・ボックスで、「ローカル」と「リモート」のどちらのプロセスに接続するかを選択します。

JConsoleのローカル・プロセスへの接続

接続するJMXエージェントを設定せずにJConsoleを起動すると、次のダイアログ・ボックスが表示されます。

図 3-1ローカル・プロセスへの接続の作成

ローカル・プロセスへの接続を作成するためのダイアログ・ボックス

ローカル・プロセス・オプションには、JConsoleと同じユーザーIDで起動され、ローカル・システム上で実行中のJava VMが、そのプロセスIDとクラス、または引数の情報とともに一覧表示されます。JConsoleをアプリケーションに接続するには、モニターするアプリケーションを選択して「接続」をクリックします。ローカル・プロセスのリストには、次のタイプのJava VMで実行中のアプリケーションが含まれます。

  • 管理エージェントが有効なアプリケーション: Java SEプラットフォーム上のアプリケーションのうち、-Dcom.sun.management.jmxremoteオプションを使用して起動したもの、または-Dcom.sun.management.jmxremote.portオプションを指定して起動したものが含まれます。また、Java SEプラットフォーム上で管理プロパティなしで起動したアプリケーションのうち、あとからJConsoleによって接続が行われ、実行時に管理エージェントを有効になったものも含まれます。

  • 接続可能で、管理エージェントが無効なアプリケーション: 実行時に管理エージェントのロードをサポートしている、接続可能なアプリケーションが含まれます。接続可能なアプリケーションには、Attach APIをサポートする、Java SEプラットフォーム上で起動したアプリケーションが含まれます。動的接続をサポートするアプリケーションについては、コマンド行でcom.sun.management.jmxremoteまたはcom.sun.management.jmxremote.portオプションを指定して管理エージェントを起動する必要ありません。JConsoleは、アプリケーションの起動前に管理エージェントに接続する必要はありません。このアプリケーションを選択すると、接続確立時に管理エージェントが有効になるという通知が画面上に表示されます。図3-1の接続ダイアログ・ボックスの例では、NetBeans IDEとJConsoleはJava SEプラットフォームVM内で起動しています。両方とも標準テキストで表示され、JConsoleが接続可能であることを示しています。図3-1では、JConsoleが選択され、通知が表示されています。

  • 接続不可能で、管理エージェントが無効なアプリケーション: Java SEプラットフォームで、-Dcom.sun.management.jmxremoteまたはcom.sun.management.jmxremote.portオプションなしで起動したアプリケーションが含まれます。これらのアプリケーションは、表にグレー表示され、JConsoleは接続できません。図3-1の接続ダイアログ・ボックスの例では、Anagramsアプリケーションは、管理プロパティでJMXエージェントを有効にせずにJava SEプラットフォームVMで起動されたため、グレー表示され選択不可になっています。

図3-2 管理エージェントを有効にせずに試行するアプリケーションへの接続

管理エージェントを有効にせずに試行するローカル・プロセスへの接続。JConsoleはこのアプリケーションに接続できない。

図3-2の接続ダイアログ・ボックスの例では、Anagramsアプリケーションが選択されていますが、「接続」はグレー表示のままで、このプロセスでは管理エージェントが有効でないという通知が表示されています。JConsoleは、起動時に正しいJava VMまたは正しいオプションを使用しなかったため、Anagramsに接続できません。

JConsoleのリモート・プロセスへの接続

接続ダイアログ・ボックスが開くと、リモート・プロセスへの接続オプションも表示されます。

図 3-3リモート・プロセスへの接続の作成

リモート・プロセスへの接続を作成するためのダイアログ・ボックス

リモートJava VM上で実行中のプロセスをモニターするには、次の情報を入力する必要があります。

  • ホスト名: Java VMが動作しているマシンの名前。

  • ポート番号: Java VMの起動時に指定したJMXエージェントのポート番号。

  • ユーザー名とパスワード: ユーザー名と使用するパスワード(パスワード認証の必要なJMXエージェントでJava VMをモニタリングする場合のみ必要)。

JMXエージェントのポート番号を設定するには、すぐに使用できる管理の有効化.を参照してください。

パスワードとアクセス・ファイルの使用を参照してください。

JConsoleを実行しているJava VMをモニターするには、「接続」をクリックし、ホストをlocalhost、ポートを0と指定します。

JMXサービスURLを使用する接続

リモート・プロセス・オプションを使用してほかのJMXエージェントに接続するには、そのエージェントのJMXサービスURL、ユーザー名、およびパスワードを指定します。JMXサービスURLの構文には、接続に使用するトランスポート・プロトコルとサービス・アクセス・ポイントを指定する必要があります。JMXサービスURLの全構文は、javax.management.remote.JMXServiceURLのAPIドキュメントに記載されています。

図 3-4 JMXサービスURLによるJMXエージェントへの接続

JMXサービスURLによるJMXエージェントへの接続

JMXエージェントがJavaプラットフォームに含まれていないコネクタを使用する場合は、jconsoleコマンドを実行するときに、次のようにコネクタ・クラスをクラス・パスに追加する必要があります。

% jconsole -J-Djava.class.path=JAVA_HOME/lib/jconsole.jar:JAVA_HOME/lib/tools.jar:connector-path

connector-pathは、JDKには含まれていないがJConsoleで使用するコネクタ・クラスがあるディレクトリまたはJavaアーカイブ(JAR)ファイルです。

JConsoleタブの表示

JConsoleをアプリケーションに接続すると、次の6つのタブがJConsoleに表示されます。

  • 概要: Java VMとモニター結果の値の概要を表示します

  • メモリー: メモリーの使用情報を表示します

  • スレッド: スレッドの使用情報を表示します

  • クラス: クラス・ローディングの情報を表示します

  • VM: Java VMの情報を表示します

  • MBean: MBeanの情報を表示します

JConsoleの右上隅にある緑の接続ステータス・アイコンを使用すると、実行中のJava VMからの切断または再接続を行うことができます。「接続」を選択し、ドロップ・ダウン・メニューから「新規接続」を選択すると、実行中の任意の数のJava VMに同時に接続できます。

概要情報の表示

「概要」タブには、CPU使用状況、メモリー使用量、スレッド数、Java VMにロードされたクラスについての、グラフィカルなモニタリング情報がすべて1つの画面に表示されます。

図3-5 「概要」タブ

JConsoleの「概要」タブ

「概要」タブを使用すれば、以前は複数のタブを切り替えることでしか利用できなかった情報の関連付けが簡単にできます。

図表データの保存

JConsoleでは、図表データをカンマ区切り値(CSV)ファイルに保存できます。図表のデータを保存するには、図表を右クリックして「別名で保存」を選択し、データの保存先のファイルを指定します。どの図表のデータでも、JConsoleのタブに表示されたものであれば、同様に保存できます。

CSV形式は、スプレッドシート・アプリケーションのデータ交換に一般的に使用されています。CSVファイルは、スプレッドシート・アプリケーションにインポートして、そのアプリケーションで図を作成する場合に使用できます。このデータは、2つ以上の名前付き列(カラム)として表示されます。最初の列はタイムスタンプを示します。ファイルをスプレッドシート・アプリケーションにインポートした後、通常は最初の列を選択し、その書式を必要に応じて「日付」または「日付/時間」に変更する必要があります。

メモリー消費のモニタリング

「メモリー」タブには、メモリー消費とメモリー・プールに関する情報が表示されます。

図3-6 「メモリー」タブ

JConsoleの「メモリー」タブ。

「メモリー」タブの「GCの実行」をクリックすると、いつでもガベージ・コレクションを実行できます。この図は、ヒープ・メモリーと非ヒープ・メモリー、および特定のメモリー・プールについて、Java VMのメモリー使用量の経時的推移を示しています。利用できるメモリー・プールは、使用しているJava VMのバージョンによって異なります。HotSpot Java VMの場合、シリアル・ガベージ・コレクションのメモリー・プールは次のとおりです。

  • Eden領域(ヒープ): ほとんどのオブジェクトにメモリーが最初に割り当てられるプール。

  • Survivor領域(ヒープ): Eden領域のガベージ・コレクションで残ったオブジェクトを含むプール。

  • Tenured世代(ヒープ): Survivor領域である程度の期間存続したオブジェクトを含むプール。

  • Permanent世代(非ヒープ): クラスやメソッド・オブジェクトなど、仮想マシン自体を反映したデータをすべて保持するプール。Java VMでクラス・データ共有を使用する場合、この世代は読取り専用領域と読取り/書込み領域に分割されています。

  • コード・キャッシュ(非ヒープ): HotSpot Java VMには、ネイティブ・コードのコンパイルとストレージに使用するメモリーを含むコード・キャッシュも含まれます。

これらのメモリー・プールの消費を示す別の図表を表示させるには、「図」ドロップ・ダウン・メニューから必要なオプションを選択します。また、右下隅の「ヒープ」または「非ヒープ」の棒グラフをクリックすると、図表の表示が切り替わります。最後に、メモリー使用量を追跡する時間の範囲指定は、「時間範囲」ドロップ・ダウン・メニューから必要なオプションを選択します。

ガベージ・コレクションを参照してください。

詳細」領域には、現在のメモリーに関するメトリックスがいくつか表示されます。

  • 使用済: 現在使用中のメモリー容量。使用中のメモリーには、すべてのオブジェクト(アクセス可能なものも不能なものも含む)によって使用されているメモリーが含まれます。

  • コミット済: Java VMで利用できることが保証されたメモリー容量。確定メモリーの容量は経時的に変わる可能性があります。Java仮想マシンがメモリーをシステムに解放した場合、確定メモリーの容量は、起動時に割り当てられた最初の容量よりも少なくなる可能性があります。確定メモリーの容量は必ず使用中のメモリー容量以上になります。

  • 最大: メモリー管理に使用できる最大メモリー容量。この値は変化する場合や定義されていない場合があります。Java VMで使用メモリー容量を確定メモリー容量より大きくしようとすると、使用量が最大以下の場合(たとえば、システムの仮想メモリーが少ない場合)でも、メモリー割当てに失敗することがあります。

  • GC時間: ガベージ・コレクションに要した累積時間とその呼出しの総数。複数行に及ぶ場合もあります。各行はJava VMで使用するガベージ・コレクタの1つのアルゴリズムを示します。

右下の棒グラフは、メモリー・プールによって、ヒープおよび非ヒープ・メモリーで使用されるメモリーを示しています。使用メモリーがメモリー使用量しきい値を超えると、棒の色が赤に変わります。メモリー使用量しきい値は、MemoryMXBeanの属性で設定できます。

ヒープおよび非ヒープのメモリー

Java VMが管理するメモリーには、ヒープ・メモリーと非ヒープ・メモリーの2種類があり、いずれもJava VMの起動時に作成されます。

  • ヒープ・メモリー: 実行時データ領域であり、Java VMはそこからすべてのクラスのインスタンスと配列にメモリーを割り当てます。ヒープのサイズは可変の場合と固定の場合があります。ガベージ・コレクタは、ヒープ・メモリーをオブジェクトに再利用する自動メモリー管理システムです。

  • 非ヒープ・メモリー: すべてのスレッドで共有されるメソッド領域と、Java VMの内部処理や最適化に必要なメモリーが含まれます。非ヒープ・メモリーには、実行定数プール、フィールドおよびメソッド・データ、メソッドおよびコンストラクタのコードなど、クラス単位の構造体が格納されます。メソッド領域は論理的にはヒープの一部ですが、実装方法によっては、Java VMがこの領域のガベージ・コレクトや圧縮を行わない場合もあります。ヒープ・メモリーと同様に、メソッド領域のサイズは固定の場合と可変の場合があります。メソッド領域のメモリーは連続している必要はありません。

メソッド領域に加えて、Java VMには、内部処理または最適化のためのメモリー(これも非ヒープ・メモリーに属します)が必要になる場合もあります。たとえば、JIT (Just-In-Time)コンパイラには、パフォーマンス向上のためにJava VMコードから変換されたネイティブ・マシン・コードを格納するためのメモリーが必要です。

メモリー・プールとメモリー・マネージャ

メモリー・プールとメモリー・マネージャは、Java VMのメモリー・システムの重要な部分です。

  • メモリー・プール: Java VMが管理するメモリー領域です。Java VMには少なくとも1つのメモリー・プールがあり、実行中にメモリー・プールを作成または削除できます。メモリー・プールは、ヒープ・メモリーと非ヒープ・メモリーのどちらかに属します。

  • メモリー・マネージャ: 1つ以上のメモリー・プールを管理します。ガベージ・コレクタは、メモリー・マネージャの一種で、アクセスできなくなったオブジェクトが使用していたメモリーの再利用を管理しています。Java VMが装備するメモリー・マネージャは1つの場合も複数の場合もあります。実行中にメモリー・マネージャを追加または削除できます。メモリー・プールは、複数のメモリー・マネージャによって管理できます。

ガベージ・コレクション

ガベージ・コレクション(GC)は、参照されていないオブジェクトが使用していたメモリーを解放する、Java VMの仕組みです。アクティブな参照を持つオブジェクトを「生きている」と考え、参照されていない(アクセスできない)オブジェクトを「死んでいる」と考えるのが一般的です。ガベージ・コレクションは、死んだオブジェクトによって使用されていたメモリーを解放するプロセスです。GCによって使用されるアルゴリズムとパラメータがパフォーマンスに劇的な効果をもたらす可能性があります。

Java HotSpot VMガベージ・コレクタは、世代別GCを使用します。世代別GCは、ほとんどのプログラムには次のような傾向があるという所見に基づいています。

  • 生成する多くのオブジェクトは短命である(イテレータやローカルの変数など)。

  • 生成する一部のオブジェクトは非常に長い寿命を持つ(高度な持続性オブジェクトなど)。

そのため、世代別のGCは、メモリーをいくつかの世代に分け、それぞれにメモリー・プールを割り当てます。ある世代が割り当てられたメモリーを使用すると、VMはメモリー・プール上で部分的なGC (マイナー・コレクションともいう)を実行して、死んだオブジェクトによって使用されたメモリーを再利用します。この部分的なGCは、通常、フルGCよりもはるかに高速です。

Java HotSpot VMは、若い世代(「nursery」ともいう)と古い世代という2つの世代を定義します。若い世代は、1つの「Eden領域」と2つの「Survivor領域」で構成されています。VMは最初にすべてのオブジェクトをEden領域に割り当て、ほとんどのオブジェクトはそこで死にます。マイナーGCを実行するとき、VMは残りのオブジェクトをEden領域からSurvivor領域の1つに移します。VMは、Survivor領域で十分に長く生きるオブジェクトを古い世代の「Tenured」領域に移します。Tenured世代がいっぱいになると、フルGCが実行されます。これは生きているオブジェクトをすべて含むため、通常はマイナーGCよりも時間がかかります。Permanent世代は、クラスやメソッド・オブジェクトなどの仮想マシン自体を反映したデータをすべて保持します。

各世代のデフォルトの配置は、図 3-7のようになります。

図 3-7ガベージ・コレクションのデータの世代

ガベージ・コレクタで世代別に定義されるデータ

ガベージ・コレクタがボトルネックになる場合、世代のサイズをカスタマイズすることによって、パフォーマンスを向上させることができます。JConsoleを使用して、ガベージ・コレクタのパラメータを試すことで、パフォーマンス・メトリックの感度を調べることができます。Java Platform, Standard Edition HotSpot仮想マシン・ガベージ・コレクション・チューニング・ガイドパフォーマンスに関する考慮事項を参照してください。

スレッドの使用のモニタリング

「スレッド」タブには、スレッドの使用に関する情報が表示されます。

図3-8 「スレッド」タブ

JConsoleの「スレッド」タブ。

左下隅の「スレッド」リストには、アクティブなスレッドがすべて表示されます。「フィルタ」フィールドに文字列を入力すると、「スレッド」リストには、入力した文字列を含む名前のスレッドだけが表示されます。「スレッド」リスト内のスレッドの名前をクリックすると、スレッド名や状態、スタック・トレースなど、そのスレッドに関する情報が右に表示されます。

この図は、ライブ・スレッドの数の経時的推移を示しています。次の2本のラインが表示されています。

  • 赤: スレッドのピーク数

  • 青: ライブ・スレッドの数

Threading MXBeanには、ほかにも「スレッド」タブにない便利な操作があります。

  • findMonitorDeadlockedThreads: オブジェクト・モニター・ロックでデッドロックに陥ったスレッドを検出します。この操作は、デッドロックに陥ったスレッドIDの配列を返します。

  • getThreadInfo: スレッド情報を返します。これには、名前とスタック・トレースのほか、スレッドが現在ブロックされている場合は該当するモニター・ロック、そのロックを保持しているスレッド、およびスレッド競合統計が含まれます。

  • getThreadCpuTime: 指定されたスレッドによるCPUの使用時間を返します。

これらの追加機能に「MBean」タブからアクセスするには、MBeanツリーで「Threading MXBean」を選択します。このMXBeanには、モニターされているJava VMのスレッド情報にアクセスするための属性と操作がすべて一覧表示されます。「MBeanのモニタリングと管理」を参照してください。

デッドロックに陥ったスレッドの検出

アプリケーションがデッドロックに陥ったのかどうかを確認する場合(たとえば、アプリケーションがハング・アップしたように見える場合)、「デッドロックの検出」をクリックすれば、デッドロックに陥ったスレッドを検出できます。デッドロックに陥ったスレッドが検出されると、図3-9のように、「スレッド」タブの横の新しいタブに表示されます。

図3-9 デッドロックに陥ったスレッド

JConsoleで検出されたスレッドのデッドロック。

「デッドロックを検出する」を使用すると、オブジェクト・モニターとjava.util.concurrent所有可能シンクロナイザを伴うデッドロック・サイクルを検出できます( java.lang.management.LockInfoのAPI仕様のドキュメントを参照)。Java SEバージョン6.0以降、java.util.concurrentロックのモニタリング・サポートが追加されました。JConsoleがJava SE 5.0 VMに接続している場合、デッドロックの検出メカニズムではオブジェクト・モニターに関するデッドロックのみが検出されます。JConsoleでは、所有可能シンクロナイザに関するデッドロックは表示されません。

スレッドとデーモン・スレッドの詳細は、APIドキュメントでjava.lang.Threadを参照してください。

クラス・ローディングのモニタリング

「クラス」タブには、クラス・ローディングの情報が表示されます。

図3-10 「クラス」タブ

この図は、ロードされたクラスの数に関する情報を示しています。

この図は、ロードされたクラス数の経時的推移を示しています。

  • 赤いラインは、ロードされたクラスの総数(そのあとアンロードされたクラスを含む)を表します。

  • 青いラインは、現在ロードされているクラスの数を表します。

タブの下の「詳細」セクションには、Java VMの起動後にロードされたクラスの総数、および現在ロードされている数とアンロードされた数が表示されます。クラス・ローディングのトレースを冗長出力に設定するには、右上隅のチェック・ボックスにチェック・マークを入れます。

VM情報の表示

「VMの概要」タブには、Java VMに関する情報が表示されます。

図 3-11「VMの概要」タブ

JConsoleの「VMの概要」タブ。

このタブには次のような情報が表示されます。

  • 概要

    • アップタイム: Java VMの合計起動時間。

    • プロセスCPU時間: Java VMが起動してからCPUを使用した合計時間。

    • コンパイルの総時間: JITコンパイルに要した累積時間。Java VMの実装方法によって、JITコンパイルのタイミングが決まります。Hotspot VMは、適応型コンパイルを採用しています。適応型コンパイルでは、VMは標準のインタプリタを使用してアプリケーションを起動しますが、コードの実行中にコードを分析して、パフォーマンスのボトルネック、つまり「ホット・スポット」を検出します。

  • スレッド

    • ライブ・スレッド: ライブ・デーモン・スレッドおよびデーモンでないライブ・スレッドの現在数。

    • ピーク: Java VM起動後のライブ・スレッドの最大数。

    • デーモン・スレッド: デーモンのライブ・スレッドの現在数。

    • 開始したスレッドの総数: Java VMの起動後に起動されたスレッドの合計数(デーモンおよびデーモン以外のスレッドと終了したスレッドを含む)。

  • クラス

    • 現在ロードされているクラス: 現在メモリーにロードされているクラスの数。

    • ロードされたクラスの総数: Java VMの起動後にメモリーにロードされたクラスの合計数(そのあとアンロードされたものを含む)。

    • アンロードされたクラスの総数: Java VMの起動後にメモリーからアンロードされたクラスの数。

  • メモリー

    • 現在のヒープ・サイズ: 現在、ヒープ単位で占めているKバイト数。

    • 確定メモリー: ヒープ用に割り当てられたメモリーの合計容量。

    • 最大ヒープ・サイズ: ヒープ単位で占めている最大Kバイト数。

    • ファイナライズを保留中のオブジェクト: ファイナライズを待機しているオブジェクト数。

    • ガベージ・コレクタ: GCに関する情報(ガベージ・コレクタ名、GCの実行回数、GCの実行に要した合計時間など)。

  • オペレーティング・システム

    • 総物理メモリー: オペレーティング・システムが保持するランダム・アクセス・メモリー(RAM)の容量。

    • 空物理メモリー: オペレーティング・システムが使用可能なRAMの空き容量。

    • 確定仮想メモリー: 実行プロセスに使用できることが保証された仮想メモリーの量。

  • その他の情報

    • VMの引数: アプリケーションがJava VMに渡した入力引数(mainメソッドの引数は含まない)。

    • クラス・パス: システム・クラス・ローダーがクラス・ファイルを検索するために使用するクラス・パス。

    • ライブラリ・パス: ライブラリをロードするときに検索するパスのリスト。

    • ブート・クラスパス: ブートストラップ・クラス・ローダーがクラス・ファイルを検索するために使用するパス。

MBeanのモニタリングと管理

「MBean」タブには、プラットフォームMBeanサーバーに通常の方法で登録されているすべてのMBeanに関する情報が表示されます。「MBean」タブから、フル・セットのプラットフォームMXBeanインストゥルメンテーション(他のタブには表示されないものも含む)にアクセスできます。そのほか、「MBean」タブを使用すれば、アプリケーションのMBeanのモニターと管理もできます。

図3-12 「MBean」タブ

JConsoleの「MBean」タブ。

左のツリーは、現在稼動中のすべてのMBeanを示しています。ツリーでMBeanを選択すると、そのMBeanInfoとMBean記述子の両方が右に表示され、その下のツリーには属性、操作、または通知が表示されます。

プラットフォームMXBeanとその各種操作および属性はすべて、JConsoleの「MBean」タブからアクセスできます。

MBeanツリーの作成

デフォルトでは、MBeanはそのオブジェクト名に対応するツリーに表示されます。オブジェクト名の作成時に指定したキー・プロパティの順序は、JConsoleによってMBeanをMBeanツリーに追加するときに保存されます。JConsoleがMBeanツリーの作成に使用する正確なキー・プロパティ・リストは、ObjectName.getKeyPropertyListString()メソッドによって返されます。その場合、最初のキーはtypeで、j2eeTypeがあればそれが2番目のキーとなります。

ただし、ObjectNameキー・プロパティの順序をデフォルトにしておくと、JConsoleがMBeanツリーをレンダリングするときに予想外の動作につながる場合があります。たとえば、2つのオブジェクト名が同じキーをもち、そのキーの順序が異なる場合、対応するMBeanは、MBeanツリーにある同じノードでは作成されません。

たとえば、Triangle MBeanオブジェクトを次の名前で作成するとしましょう。

com.sun.example:type=Triangle,side=isosceles,name=1
com.sun.example:type=Triangle,name=2,side=isosceles
com.sun.example:type=Triangle,side=isosceles,name=3

JMXテクノロジに関するかぎり、これらのオブジェクトはまったく同様に扱われます。オブジェクト名内のキーの順序は、JMXテクノロジにとって重要ではありません。しかし、JConsoleをこれらのMBeanに接続し、デフォルトでレンダリングされたMBeanツリーを使用すると、オブジェクトcom.sun.example:type=Triangle,name=2,side=isoscelesTriangleノードの下に2というノード名で作成されます。このノード2にはisoscelesというサブノードが追加されます。他の2つの二等辺三角形(name=1name=3)は、図3-13のように、Triangleの下にisoscelesという別名ノードでグループ化されます。

図 3-13予想外にレンダリングされたMBeanツリーの例

予想外にレンダリングされたMBeanツリーの例

この問題を回避するには、コマンド行でJConsoleを起動するときにキー・プロパティ・リストを正しい順序で入力することにより、MBeanがツリーに表示される順序を指定します。これを実行するには、次のコマンドのように、システム・プロパティcom.sun.tools.jconsole.mbeans.keyPropertyListを設定します。

% jconsole -J-Dcom.sun.tools.jconsole.mbeans.keyPropertyList=key[,key]*

キー・プロパティ・リストのシステム・プロパティにより、キーのカンマ区切りリストは選択された順序で表示されます。この場合のkeyは、必ずオブジェクト名のキーを表す文字列または空の文字列とします。リストで指定されたキーが特定のMBeanに適用されない場合、そのキーは破棄されます。キー・プロパティ・リストで指定されたキーよりも多数のキーがMBeanにある場合、ObjectName.getKeyPropertyListString()の戻り値で定義されたキーの順序が、keyPropertyListで定義されたキーの順序を補完します。したがって、空のキー・リストを指定すると、JConsoleのキーの表示は、MBeanのObjectNameの表示と同じ順序になります。

前述のTriangle MBeanの例に戻ると、JConsoleを起動するときにkeyPropertyListシステム・プロパティを指定すれば、sideが先、nameが後というキー・プロパティの順序に従って、すべてのMBeanがグループ化されます。これを行うには、次のコマンドでJConsoleを起動します。

% jconsole -J-Dcom.sun.tools.jconsole.mbeans.keyPropertyList=side,name

このシステム・プロパティを指定してJConsoleを起動すると、図3-14のようなMBeanツリーが生成されます。

図 3-14 keyPropertyListを使用して生成されたMBeanツリーの例

keyPropertyListを使用して生成されたMBeanツリーの例

図 3-14では、sideキーが先、nameキーが後になります。typeキーが最後になるのは、キー・プロパティ・リストに指定されていなかった場合に、MBeanツリーのアルゴリズムによって残りのキーには元のキーの順序が適用されたためです。結果として、typeキーの順序は、keyPropertyListシステム・プロパティで定義されたキーの後になります。

JMXベスト・プラクティス・ガイドライン」で定義されたオブジェクトの命名規約に従えば、typeキーは必ず先頭にくるはずです。次のシステム・プロパティを使用してJConsoleを起動する必要があります。

% jconsole -J-Dcom.sun.tools.jconsole.mbeans.keyPropertyList=type,side,name

上のコマンドにより、JConsoleは図3-15のようなTriangle MBeanのMBeanツリーを生成します。

図 3-15 JMXベスト・プラクティスに従って生成されたMBeanツリーの例

JMXベスト・プラクティスに従って生成されたMBeanツリーの例

これで図3-13図3-14のMBeanツリーよりもわかりやすくなります。

MBean属性

「Attributes」ノードを選択すると、MBeanの属性がすべて表示されます。図 3-16は、ThreadingプラットフォームMXBeanのすべての属性を示しています。

図 3-16すべてのMBean属性の表示

Threading MBeanの属性の表示。

図 3-17のように、ツリーから個別のMBean属性を選択すると、その属性値、MBeanAttributeInfo、関連する記述子が右側のペインに表示されます。

図 3-17個別のMBean属性の表示

「MBean」タブによるMBean属性の表示。

属性値が太字で表示されている場合、これをダブルクリックすると、その属性の追加情報が表示されます。たとえば、java.lang.Memory MBeanのHeapMemoryUsage属性の値をクリックすると、図3-18のような図表が表示されます。

図 3-18属性値の表示

MBeanの属性値の表示。

属性の数値をダブルクリックすると、その数値の変化を示す図表が表示されます。たとえば、Garbage Collector MBean PS MarksweepCollectionTime属性をダブルクリックすると、ガベージ・コレクションに要した時間が表示されます。

JConsoleでは、書込み可能な属性値の設定もできます。書込み可能な属性値は青で表示されます。ここにはMemory MBeanのVerbose属性が表示されます。

図 3-19書込み可能な属性値の設定

MBeanの書込み可能な属性値の設定。

属性を設定するには、属性をクリックして編集します。たとえば、JConsoleでガベージ・コレクタの冗長トレースを有効または無効にするには、「MBean」タブで「Memory MXBean」を選択し、Verbose属性をtrueまたはfalseに設定します。同様に、クラス・ローディングMXBeanにもVerbose属性があり、これを設定すれば、クラス・ローディング冗長トレースを有効または無効に切り替えることができます。

MBeanの操作

「Operations」ノードを選択すると、MBeanの操作がすべて表示されます。MBean操作はボタンとして表示され、これらをクリックすることで操作を呼び出すことができます。図3-20は、ThreadingプラットフォームMXBeanのすべての操作を示しています。

図 3-20すべてのMBean操作の表示

ThreadingプラットフォームMXBeanの操作の表示。

ツリーから個別のMBean操作を選択すると、図3-21のように、MBean操作を呼び出すボタン、その操作のMBeanOperationInfo、およびその記述子が表示されます。

図 3-21個別のMBean操作の表示

MBeanの操作の呼出し。
MBeanの通知

通知の受信に登録するには、左ツリーから「Notifications」ノードを選択し、右に表示される「登録」ボタンをクリックします。通知の受信数は角カッコの中に表示され、新しい通知を受信すると「Notifications」ノード自体が太字で表示されます。MemoryプラットフォームMXBeanの通知を図 3-22に示します。

図 3-22 MBean通知の表示

MBeanの通知の表示。

個別のMBean通知を選択すると、図 3-23のように、MBeanNotificationInfoが右側のペインに表示されます。

図 3-23個別のMBean通知の表示

MBean通知の受信の登録。
HotSpot Diagnostic MXBean

JConsoleの「MBean」タブでは、HotSpot VMにヒープ・ダンプの実行を指示し、HotSpotDiagnostic MXBeanを使用してVMオプションを取得または設定することもできます。

図 3-24 HotSpot診断MBeanの表示

HotSpot VM診断MBeanによるヒープ・ダンプの実行。

ヒープ・ダンプを手動で行うには、com.sun.management.HotSpotDiagnostic MXBeanのdumpHeap操作を呼び出します。また、setVMOption操作を使用してHeapDumpOnOutOfMemoryError Java VMオプションを指定し、OutOfMemoryErrorを受け取ると必ずVMで自動的にヒープ・ダンプが実行されるようにすることもできます。

カスタム・タブの作成

既存の標準タブのほか、独自のカスタム・タブをJConsoleに追加して、独自のモニタリング・アクティビティを行うこともできます。JConsoleプラグインAPIには、たとえば、独自のアプリケーションのMBeanにアクセスするタブを追加するメカニズムがあります。JConsoleプラグインAPIは、独自のカスタム・プラグインを作成するために拡張可能なabstractクラスであるcom.sun.tools.jconsole.JConsolePluginを定義しています。

前述のように、独自のプラグインは、JConsolePluginを拡張し、JConsolePlugingetTabsおよびnewSwingWorkerメソッドを実装する必要があります。getTabsメソッドは、JConsoleに追加するタブのリストと空リストのどちらかを返します。newSwingWorkerメソッドは、そのプラグインのGUIを更新するSwingWorkerを返します。

独自のプラグインはJavaアーカイブ(JAR)ファイルで提供され、それにはMETA-INF/services/com.sun.tools.jconsole.JConsolePluginというファイルが入っている必要があります。このJConsolePluginファイル自体には、新しいJConsoleタブとして追加するプラグインの完全修飾クラス名のリストが含まれています。JConsoleは、サービス・プロバイダのロード機能を使用して、プラグインの検索とロードを実行します。JConsolePluginでは、プラグインごとのエントリを1つにして、複数のプラグインをもつこともできます。

新しいカスタム・プラグインをJConsoleにロードするには、JConsoleを次のコマンドで起動します。

%  jconsole -pluginpath plugin-path

前のコマンドで、plugin-pathは、検索するJConsoleプラグインへのパスを指定しています。これらのパスではディレクトリ名またはJARファイルを指定し、プラットフォームの標準区切り文字を使用して複数のパスを指定することもできます。

Java SE 13プラットフォームにはJConsoleプラグインのサンプルが付属します。JTopアプリケーションは、このアプリケーションで実行されるすべてのスレッドのCPU使用状況を示すJDKデモ・アプリケーションです。このデモはCPU消費が多いスレッドの識別に便利で、JConsoleプラグインやスタンドアロンのGUIとして使用できるように更新されています。JTopは、デモ・アプリケーションとしてJava SE 13プラットフォームにバンドルされています。JTopプラグインを使用してJConsoleを起動するには、次のコマンドを実行します。


% JDK_HOME/bin/jconsole -pluginpath JDK_HOME/demo/management/JTop/JTop.jar

このJConsoleのインスタンスに接続すると、「JTop」タブが追加され、実行中の各種スレッドのCPU使用状況が表示されます。

図 3-25カスタム・プラグイン・タブの表示

サンプル・プログラムJTopに接続されたカスタム・タブの表示。