JSTackは、特定のJavaプロセスIDまたはコアファイル、またはリモートデバッグサービスのJavaスタック情報を印刷するために使用されます。 64ビットマシン上にある場合は、オプション「-J-D64」を指定する必要があります。 Windows JStackの使用は、次の方法のみをサポートしています。
jstack [-l] [f] pid
Javaプログラムがクラッシュしてコアファイルを生成すると、JSTackツールを使用して、Javaスタックとコアファイルのネイティブスタックに関する情報を取得できます。そのため、Javaプログラムのクラッシュ方法とプログラムの問題が簡単にわかります。さらに、JSTackツールを実行中のJavaプログラムに添付し、当時実行されていたJavaプログラムのJavaスタックとネイティブスタックに関する情報を確認することもできます。実行中のJavaプログラムがHungの状態をレンダリングするようになった場合、JStackは非常に便利です。プロセスがHungの死んだ状態にある場合、-Fでスタックを強制的に再生することができます。
ダンプファイルでは、注意を払う価値のあるスレッドステータスは次のとおりです。
デッドロック、デッドロック(焦点)
実行可能
状態を待っている(焦点を合わせて)
モニターエントリを待っています(焦点)
一時停止中
オブジェクト待機、object.wait()またはtimed_waiting
ブロック、ブロック(焦点)
停止して、駐車した
別のブログから3つのシナリオを見てみましょう。
例1:ロックしてブロックするのを待っています
「RMI TCP接続(267865)-172.16.5.25 "デーモンPrio = 10 Tid = 0x00007FD508371000 NID = 0x555AEモニターエントリを待っている[0x000007FD4F8684000] Java.lang.thread. org.apache.log4j.category.callappenders(category.java:201) - org.apache.log4j.category.forcedlog(category.java:388)at org.apache.log4j.category.forcedlog(apache.log4j.logger)のロックを待っていますorg.apache.log4j.category.log(category.java:853)at org.apache.commons.logging.impl.log4jlogger.warn(log4jlogger.java:234)at com.tuan.core.common.lang.cache.remote.spymemcachedclient.get(spymemcachedclient.java:110)
説明:
1)スレッド状態がブロックされ、ブロックされます。つまり、スレッドがリソースがタイムアウトするのを待つことを意味します!
2)「ロックするのを待つ<0x000000ACF4D0C0>」とは、スレッドが0x000000ACF4D0C0アドレスをロックするのを待っていることを意味します(英語では、0x0000000000ACF4D0C0ロックを取得しようとする)。
3)ダンプログで文字列0x00000000ACF4D0C0を検索すると、このアドレスをロックするのを待っている多数のスレッドがあることがわかりました。ログでこのロックを取得した人(ロックされた<0x000000ACF4D0C0>など)を見つけることができる場合は、手がかりに従うことができます。
4)「モニターエントリを待つ」とは、このスレッドが同期(OBJ){...}アプリケーションを介してクリティカルエリアに入ることを意味します。したがって、以下の図1に「エントリセット」キューに入ります。ただし、OBJに対応するモニターは他のスレッドが所有しているため、このスレッドはエントリセットキューで待機します。
5)最初の行では、「RMI TCP接続(267865)-172.16.5.25」はスレッド名です。 TIDはJavaスレッドIDを指します。 NIDは、ネイティブスレッドのIDを指します。 Prioはスレッドの優先度です。 [0x00007FD4F8684000]は、スレッドスタックの開始アドレスです。
例2:条件とtimed_waitingを待っています
「RMI TCP接続(IDLE)」デーモンPrio = 10 TID = 0x00007FD50834E800 NID = 0x56B2 nid = 0x56b2条件で[0x000007fd4f1a59000] java.lang.thread.state:sunsafe.unsafe.unsafe.unsafe.parkのために駐車のために待機します(駐車場) <0x00000000ACD84DE8>(a java.util.concurrent.synchronousqueue $ transferstack)java.util.concurrent.locks.locksupport.parknanos(locksupport.java:198)at java.util.concurrent.synchronousqueue $ transferstack.awaitfulfill(synchronousqueue.java:424)at java.util.concurrent.synchronousqueue $ transferstack.transfer(synchronousqueue.java:323)at java.util.concurrent.synchronousqueue.poll(synchronousqueue.java:874)at java.util.concurrent.threadpoolexecutor.gettask(threadpoolexecutor.java:945)at java.util.concurrent.threadpoolexecutor $ worker.run(threadpoolexecutor.java:907)at java.lang.thread.run(thread.java:662)
説明:
1)「Timed_Waiting(駐車)」のTimed_Waitingは待機状態を指しますが、ここでは時間が指定されており、指定された時間に達した後に待機状態が自動的に終了します。駐車場とは、スレッドが中断されることを指します。
2)「駐車場」と組み合わせる必要があります。「駐車場は、<0x00000000ACD84DE8>(a java.util.concurrent.synchronousqueue $ transferstack)を待機します。まず第一に、このスレッドは間違いなく特定の状態が目覚めるのを待っています。第二に、Synchronousqueueはキューではなく、スレッド間で情報を引き渡すためのメカニズムにすぎません。 Synchronousqueueに要素を配置すると、タスクが引き渡されるのを待っている別のスレッドが必要なので、これがこのスレッドが待っている状態です。
3)他に何も見えません。
例3:obejct.wait()およびtimed_waitingで
「RMI RenewClean- [172.16.5.19:28475]」デーモンPrio = 10 Tid = 0x0000000041428800 nid = 0xb09 in object.wait()[0x00007f34f4bd0000] java.lang.thread.thread.state(オブジェクト)方法) - <0x000000AA672478>(java.lang.referencequeue $ lock)でjava.lang.ref.ReferenceQueue.Remove(ReferenceQue.Java:118)で待機しています。 sun.rmi.transport.dgcclient $ endpointentry $ inlebycleanthread.run(dgcclient.java:516)at java.lang.thread.run(thread.java:662)
説明:
1)「Timed_waiting(Object Monitor)」この例では、このスレッドはjava.lang.object.wait(長いタイムアウト)を呼び出し、待機状態に入るためです。
2)「待機セット」の待機スレッド状態は、「Object.Wait()」です。スレッドがモニターを取得してクリティカルセクションに入ると、スレッドが実行され続けることが満たされていないことが判明した場合、オブジェクトのwait()メソッド(通常は同期)を呼び出し、モニターを放棄し、「wait set」キューに入ります。他のスレッドがオブジェクト上でnotify()またはnotifyall()を呼び出す場合にのみ、「待機セット」のスレッドは競合する機会を得ますが、1つのスレッドのみがオブジェクトのモニターを取得し、実行状態に戻ります。
3)RMI RenewCleanはDGCCLIENTの一部です。 DGCとは、分散GC、つまり分散ガベージコレクションを指します。
4)最初にロックされていることに注意してください<0x0000000AA672478> <0x0000000AA672478>で待機してください。最初にロックしてから同じオブジェクトを等しくする理由は、以下のコードの実装を確認するためです。
静的プライベートクラスロック{};プライベートロックロック= new Lock(); public Reference <? t> remove(long timeout){synchronized(lock){参照<? t> r = realypoll()を拡張します。 if(r!= null)return r; for(;;){lock.wait(timeout); r = reallypoll(); …}}つまり、スレッドの実行中に、このオブジェクトのモニターは、最初に同期して取得されます(ロックされた<0x0000000AA672478>に対応)。 lock.wait(Timeout);に実行されると、スレッドはモニターの所有権を放棄し、「待機セット」キュー(<0x00000000AA672478>の待機に対応)に入ります。
5)スタック情報から判断すると、リモートオブジェクトへのリモート参照がクリーニングされています。参照されたリースが到着し、分配されたガベージコレクションが1つずつクリーンアップしています。
参照:
JSTACK分析の例コードを介してプロセスデッドロックの問題を解決します
要約します
上記は、Javaスレッドダンプ分析ツールJStackの分析と使用シナリオに関するすべてです。すべての人に役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!