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スレッドのスレッド・スタック(スレッドの状態など)で構成されています。スレッド・ダンプによってアプリケーションが終了することはなく、スレッド情報が出力された後もアプリケーションは続行します。
例2-35は、スレッド・ダンプを示しています。
例2-35 JVMのすべての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ハンドラは、スレッド・スタックだけでなく、デッドロック検出アルゴリズムも実行します。デッドロックが検出された場合、例2-36に示すように、Ctrl+Breakハンドラは、デッドロックされた各スレッドに関するスレッド・ダンプの後に追加情報を出力します。
例2-36 デッドロック・スレッドの追加情報
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ハンドラはヒープ・サマリーも出力します。例2-37では、さまざまな世代(ヒープ領域)がそのサイズ、使用量、アドレス範囲とともに示されています。アドレス範囲は特に、pmap
などのツールでプロセスを調査する場合にも役立ちます。
例2-37 ヒープ・サマリー
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ハンドラはヒープ・ヒストグラムを生成します。