この項では、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の詳細は、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メソッドの名前も出力します。例2-381は、スレッドがread
システム・コールを呼び出したときに完全なスタック・トレースを出力する単純なDスクリプトです。
例2-38 DTraceによるプローブ・ポイントでのスタック・トレース
#!/usr/sbin/dtrace -s syscall::read:entry /pid == $1 && tid == 1/ { ustack(50, 0x2000); }
例2-38のスクリプトはread.d
というファイルに格納され、例2-39に示すように、トレース対象のJavaプロセスのPIDを指定することで実行されます。
Javaアプリケーションで多数のI/Oが生成されたり、なんらかの予期しない遅延が発生したりした場合、DTraceツールやそのustack()
アクションを使用すれば、問題を診断しやすくなる可能性があります。
pmap
ユーティリティは、Oracle Solaris 10オペレーティング・システムでスタック・セグメントがテキスト[stack]
付きで出力されるように改善されました。このテキストはスタックの場所を見つけるのに役立ちます。
例2-40は、改善されたpmapツールによるスタック・トレースを示しています。
例2-40 改善された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
ユーティリティはJavaをサポートしていませんでした。解釈済みおよびコンパイル済みJavaメソッドの両方で、16進アドレスを出力していました。
Oracle Solaris 10オペレーティング・システム以降のpstack
コマンド行ツールは、コア・ファイルまたはライブ・プロセスから混合モードのスタック・トレース(JavaおよびC/C++フレーム)を出力します。このツールは、解釈済、コンパイル済、およびインライン化されたJavaメソッドに対し、Javaメソッド名を出力します。