| Interstage Application Server トラブルシューティング集 |
目次
索引
![]()
|
| 第18章 Java実行環境運用時の異常 | > 18.2 スレッドダンプの見方 |
スレッドダンプはJavaプロセスの各スレッドのスタックトレースです。このスタックトレースを解析することで、そのプロセスの動作や問題点の調査を確認することが可能です。
スレッドダンプはアプリケーションがタイムアウトまたは無応答になった場合に自動採取されます。
|
アプリケーション |
出力方法 |
出力場所 |
|---|---|---|
|
Servlet/JSP/EJBアプリケーション |
アプリケーションがタイムアウトまたは無応答になった場合に自動採取。 |
コンテナ情報ログ(info.log) |
|
その他のJavaアプリケーション |
|
標準出力 |
スレッドダンプはJavaプロセスの各スレッドの情報を参照することができるため、ハング時、特にデッドロックが発生している場合に、原因調査に有効な情報を与えます。
以下にデッドロックのサンプルプログラムと、スレッドダンプの出力例を示します。
********************************************************************************
public class Deadlock implements Runnable {
volatile boolean finished = false;
public void run() {
try {
synchronized (this) {
while (!finished) {
System.out.print(".");
Thread.sleep(500);
}
}
}
catch (InterruptedException ex) {
ex.printStackTrace(System.out);
Thread.currentThread().interrupt();
}
}
public static void main(String args[]) {
Object obj = new Object();
Deadlock test = new Deadlock();
Thread th = new Thread(test, "Child");
try {
th.start();
Thread.sleep(5000);
synchronized (test) {
test.finished = true;
}
}
catch (Exception ex) {
ex.printStackTrace(System.out);
}
}
}
********************************************************************************
本サンプルプログラムは、run()メソッドで DeadLockクラスのインスタンスに対してsynchronized句により、ロックを取得しています。run()メソッドは、finishedフラグがfalseの間ループを繰り返します。
一方、main()メソッドは、run()メソッド呼出し後に、DeadLockクラスのインスタンスに対してロックを獲得できたならば、finishedフラグをtrueに設定します。この例の場合run()メソッドが、DeadLockクラスのインスタンスに対してロックを獲得していますので、main()メソッドはロックを獲得することができずに、ハングアップします。
スレッドダンプの出力例は次のとおりです。
********************************************************************************
"Thread-0" prio=10 tid=0x8ae1d0 nid=0x658 waiting on monitor [0..0x8eefd38]
"Child" prio=5 tid=0x89d9038 nid=0x630 waiting on monitor [0x8d8f000..0x8d8fdbc]
at java.lang.Thread.sleep(Native Method)
at Deadlock.run(Deadlock.java:9)
- locked <29700b8> (a Deadlock)
at java.lang.Thread.run(Thread.java:479)
"Signal Dispatcher" daemon prio=10 tid=0x80f5a0 nid=0x674 waiting on monitor [0..0]
"Finalizer" daemon prio=9 tid=0x8990d10 nid=0x2b0 waiting on monitor [0x8c4f000..0x8c4fdbc]
at java.lang.Object.wait(Native Method)
- waiting on <2930328> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:103)
- locked <2930328> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:157)
"Reference Handler" daemon prio=10 tid=0x8990078 nid=0x444 waiting on monitor [0x8c0f000..0x8c0fdbc]
at java.lang.Object.wait(Native Method)
- waiting on <2930238> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:415)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:105)
- locked <2930238> (a java.lang.ref.Reference$Lock)
"main" prio=5 tid=0x282900 nid=0x6a4 waiting for monitor entry [0x6f000..0x6fc34]
at Deadlock.main(Deadlock.java:26)
- waiting to lock <29700b8> (a Deadlock)
"VM Thread" prio=5 tid=0x28d9c8 nid=0x6cc runnable
"VM Periodic Task Thread" prio=10 tid=0x803ae8 nid=0x628 waiting on monitor
"Suspend Checker Thread" prio=10 tid=0x80ec58 nid=0x6dc runnable
********************************************************************************
各スレッドの情報は、スタックトレースの見方と同じで、下から参照します。
本スレッドダンプの場合、デッドロックの状況ですのでlock情報を確認します。
この事例では、「→」で示したスレッド間でデッドロックしていることがわかります。
ループを調べるためには、複数回スレッドダンプを採取し、同じスレッドが動作していないか確認します。
応答がない場合に要求(Request)待ちのメソッドが出ていないか確認し、そこから原因を調査する方法もあります。
また、スレッドダンプについては、“スレッドダンプが出力された場合の対処”も参照してください。
目次
索引
![]()
|