Interstage Application Server チューニングガイド |
目次
索引
![]() ![]() |
第8章 JDK/JREのチューニング | > 8.3 チューニング/デバッグ技法 |
スレッドダンプには、Javaプロセスの各スレッドの情報(スタックトレース形式)が含まれているため、ハングアップやデッドロックなどの動作具合を調査することができます。
スレッドダンプの出力先は、標準出力です。スレッドダンプが出力される契機および出力先を、表1に示します。
プログラムの種類 |
出力契機 |
出力先 |
J2EEアプリケーション |
アプリケーションがタイムアウトまたは無応答になった場合に自動採取されます。 |
コンテナ情報ログ(info.log) |
J2EE以外のJavaプログラム |
|
コンソール(標準出力) |
図1の出力例をもとにして、スレッドダンプの解析方法を説明します。
1 :public class DeadlockSample { 2 : static boolean flag; 3 : static Thread1 thread1; 4 : static Thread2 thread2; 5 : 6 : public static void main(String[] args) { 7 : thread1 = new Thread1(); 8 : thread2 = new Thread2(); 9 : thread1.start(); 10: thread2.start(); 11: } 12:} 13: 14:class Thread1 extends Thread { 15: public Thread1(){ 16: super("Thread1"); 17: } 18: 19: public void run(){ 20: synchronized(this){ 21: System.out.println("Thread1開始"); 22: while(DeadlockSample.flag==false){ // Thread2が開始するのを待つ 23: yield(); 24: } 25: DeadlockSample.thread2.method(); 26: notify(); 27: } 28: } 29: 30: public synchronized void method(){ 31: try{wait(1000);}catch(InterruptedException ex){} 32: System.out.println("Thread1.method()終了"); 33: } 34:} 35: 36:class Thread2 extends Thread { 37: public Thread2(){ 38: super("Thread2"); 39: } 40: 41: public void run() { 42: synchronized(this){ 43: DeadlockSample.flag = true; 44: System.out.println("Thread2開始"); 45: DeadlockSample.thread1.method(); 46: notify(); 47: } 48: } 49: 50: public synchronized void method() { 51: try{wait(1000);}catch(InterruptedException ex){} 52: System.out.println("Thread2.method()終了"); 53: } 54:} |
図1のサンプルでは、Thread1とThread2がお互いに排他処理を行っています。
このサンプルを実行すると、次のように処理が進められます。
この結果、Thead1とThread2がお互いに、解放されないロックを待ち続けるデッドロック状態になります。
デッドロック状態で、スレッドダンプを採取したものを、図2に示します。
"DestroyJavaVM" prio=5 tid=0x002856c8 nid=0x5f4 waiting on condition [0..6fad8] "Thread2" prio=5 tid=0x0092f4d8 nid=0x640 waiting for monitor entry [182ef000..182efd64] at Thread1.method(DeadlockSample.java:31) - waiting to lock <0x1002ffe8> (a Thread1) at Thread2.run(DeadlockSample.java:45) - locked <0x10030ca0> (a Thread2) "Thread1" prio=5 tid=0x0092f370 nid=0x294 waiting for monitor entry [182af000..182afd64] at Thread2.method(DeadlockSample.java:51) - waiting to lock <0x10030ca0> (a Thread2) at Thread1.run(DeadlockSample.java:25) - locked <0x1002ffe8> (a Thread1) "Signal Dispatcher" daemon prio=10 tid=0x0098eb80 nid=0x634 waiting on condition [0..0] "Finalizer" daemon prio=9 tid=0x0092a540 nid=0x5e8 in Object.wait() [1816f000..1816fd64] at java.lang.Object.wait(Native Method) - waiting on <0x10010498> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111) - locked <0x10010498> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159) "Reference Handler" daemon prio=10 tid=0x0096da70 nid=0x5e4 in Object.wait() [1812f000..1812fd64] at java.lang.Object.wait(Native Method) - waiting on <0x10010388> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:429) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:115) - locked <0x10010388> (a java.lang.ref.Reference$Lock) "VM Thread" prio=5 tid=0x0096c950 nid=0x624 runnable "VM Periodic Task Thread" prio=10 tid=0x0092c008 nid=0x2a0 waiting on condition "Suspend Checker Thread" prio=10 tid=0x0098e118 nid=0x478 runnable Found one Java-level deadlock: ============================= "Thread2": waiting to lock monitor 0x00929c3c (object 0x1002ffe8, a Thread1), which is held by "Thread1" "Thread1": waiting to lock monitor 0x00929c5c (object 0x10030ca0, a Thread2), which is held by "Thread2" Java stack information for the threads listed above: =================================================== "Thread2": at Thread1.method(DeadlockSample.java:31) - waiting to lock <0x1002ffe8> (a Thread1) at Thread2.run(DeadlockSample.java:45) - locked <0x10030ca0> (a Thread2) "Thread1": at Thread2.method(DeadlockSample.java:51) - waiting to lock <0x10030ca0> (a Thread2) at Thread1.run(DeadlockSample.java:25) - locked <0x1002ffe8> (a Thread1) Found 1 deadlock. |
スレッドダンプの各スレッドの情報は、スタックトレース形式です。
Thread1とThread2の両方のスタックトレースには、“locked”と“waiting to lock”があります。また、スレッドダンプの下の方にも、“deadlock”の文字列があり、デットロックが発生していることが確認できます。
このように、スレッドダンプで全スレッドの動作状況を確認するにより、Javaプロセスがハングアップしているか、あるいは、デッドロック状態かを確認することができます。特に、短い間隔で複数のスレッドダンプを採取し、スレッドに動きがなければ、ハングアップの可能性があります。
スレッドダンプの詳細は、“トラブルシューティング集”の“スレッドダンプが出力された場合の対処”も参照してください。
目次
索引
![]() ![]() |