標籤:java線程的堆疊追蹤之jstack篇
1.Jstack使用介紹
該命令列印java線程的堆疊追蹤,可以得知哪些線程被阻塞或正等待,以便於尋找如線程死結的原因
用法:
jstack [ option ] pidjstack [ option ] executable corejstack [ option ] [[email protected]]remote-hostname-or-IP
常用選項:
-F 當’jstack [-l] pid’沒有相應的時候強制列印棧資訊-l 長列表. 列印關於鎖的附加資訊,例如屬於java.util.concurrent的ownable synchronizers列表.-m 列印java和native c/c++架構的所有棧資訊.常用參數:core 將被列印資訊的core dump檔案remote-hostname-or-IP 遠程debug服務的主機名稱或ipserver-id 唯一id,假如一台主機上多個遠程debug服務id 需要被列印配置資訊的java進程id,可以用jps查詢
2.tomcat線程狀態的種類
1.線程狀態為“waiting on condition”
說明它在等待另一個條件的發生,來把自己喚醒,或者乾脆它是調用了 sleep(N)。
此時線程狀態大致為以下幾種:
?java.lang.Thread.State: WAITING (parking):一直等那個條件發生;
?java.lang.Thread.State: TIMED_WAITING (parking或sleeping):定時的,那個條件不到來,也將定時喚醒自己。
如果大量線程在“waiting on condition”:
可能是它們又跑去擷取第三方資源,尤其是第三方網路資源,遲遲擷取不到Response,導致大量線程進入等待狀態。
所以如果你發現有大量的線程都處在 Wait on condition,從線程堆棧看,正等待網路讀寫,這可能是一個網路瓶頸的徵兆,因為網路阻塞導致線程無法執行。
執行個體1:定時的,那個條件不到來,也將定時喚醒自己。
"ContainerBackgroundProcessor[StandardEngine[Catalina]]" daemon prio=10 tid=0x00007f67a419a800 nid=0x4655 waiting on condition [0x00007f679a3fd000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1510) at java.lang.Thread.run(Thread.java:745)
執行個體2:一直等那個條件發生
"http-nio-8080-exec-1" daemon prio=10 tid=0x00007f677ca95800 nid=0x46a8 waiting on condition [0x00007f679a47e000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000007a0399b28> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104) at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745)
1)“TIMED_WAITING (parking)”中的 timed_waiting 指等待狀態,但這裡指定了時間,到達指定的時間後自動結束等待狀態;parking指線程處於掛起中。
2)“waiting on condition”需要與堆棧中的“parking to wait for <0x00000000acd84de8> (a java.util.concurrent.SynchronousQueue$TransferStack)” 結合來看。首先,本線程肯定是在等待某個條件的發生,來把自己喚醒。其次,SynchronousQueue 並不是一個隊列,只是線程之間移交資訊的機制,當我們把一個元素放入到 SynchronousQueue 中時必須有另一個線程正在等待接受移交的任務,因此這就是本線程在等待的條件
執行個體3
"RMI RenewClean-[10.24.189.110:1919]" daemon prio=10 tid=0x00007f6764ee1000 nid=0x4764 in Object.wait() [0x00007f67859b9000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135) - locked <0x00000007a1bca328> (a java.lang.ref.ReferenceQueue$Lock) at sun.rmi.transport.DGCClient$EndpointEntry$RenewCleanThread.run(DGCClient.java:535) at java.lang.Thread.run(Thread.java:745)
執行個體4
"Timer-8" daemon prio=10 tid=0x00007f676c032800 nid=0x5b7d in Object.wait() [0x00007f6785833000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.util.TimerThread.mainLoop(Timer.java:552) - locked <0x00000007b47c7630> (a java.util.TaskQueue) at java.util.TimerThread.run(Timer.java:505)
2.線程狀態為“waiting for monitor entry”:
意味著它 在等待進入一個臨界區 ,所以它在”Entry Set“隊列中等待。
此時線程狀態一般都是 Blocked:
java.lang.Thread.State: BLOCKED (on object monitor)
3.如果大量線程在“waiting for monitor entry”:
可能是一個全域鎖阻塞住了大量線程。
如果短時間內列印的 thread dump 檔案反映,隨著時間流逝,waiting for monitor entry 的線程越來越多,沒有減少的趨勢,可能意味著某些線程在臨界區裡呆的時間太長了,以至于越來越多新線程遲遲無法進入臨界區。
3.執行個體操作:
[[email protected] conf]# jps
13886 Jps21147 Application13614 Bootstrap
[[email protected] conf]# jstack 13614|grep "java.lang.Thread.State"|grep parking java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: WAITING (parking) java.lang.Thread.State: TIMED_WAITING (parking)
[[email protected] conf]# jstack 13614|grep "java.lang.Thread.State"|grep parking|wc -l
41
java.lang.Thread.State: WAITING (parking) 的數量等於minsparethread最小閒置線程數的數值
檢查 是否存在死結
[[email protected]_82_178_redhat ~]# jstack -l -F 7523
Attaching to process ID 7523, please wait...Debugger attached successfully.Server compiler detected.JVM version is 25.60-b23Deadlock Detection:**No deadlocks found**.
java線程的堆疊追蹤之jstack篇