1. 程式人生 > 其它 >效能問題之執行緒死鎖

效能問題之執行緒死鎖

定義

執行緒死鎖就是有兩個執行緒,一個執行緒鎖住了資源A,又想去鎖住資源B,另外一個執行緒鎖定了資源B,又想去鎖定資源A,兩個執行緒都想去得到對方的資源而又不願意釋放自己的資源,從而造成了一種互相等待、無法執行的情況。

 

現象

出現死鎖後,TPS降為0,效能測試工具無法得到伺服器的響應,

伺服器硬體資源空閒

通過jvisualvm去檢視執行緒情況,至少兩個執行緒一直處於紅色的阻塞狀態

 

案例分析

1、某介面壓測5分鐘結果如下:

從上面三幅圖片可以看出:

  (1)從測試工具jmeter可以看出,5分鐘還未到,測試過程還在繼續,但是其實從第15秒之後就沒有請求。

  (2)檢視機器資源,從圖中可以得出,機器的CPU資源佔用率很低,遠未達到瓶頸。

根據執行緒死鎖的現場,猜測此時是發生了執行緒死鎖。

 

 2、驗證猜想

方法一:通過jstack命令檢視執行緒情況。對執行緒程式碼進行分析,獲取到哪行程式碼導致的死鎖。

jstack pid > filename.log

將dump下來的檔案下載到本地,通過deadlock進行查詢:

把圖中的Deadlock內容複製出來:

http-nio-8080-exec-9- waiting to lock <0x00000000e6a31c68>
    - locked <0x00000000e6a31c88>
http-nio-8080-exec-1- waiting to lock
<0x00000000e6a31c88> - locked <0x00000000e6a31c68>
由上可知:執行緒http-nio-8080-exec-9和http-nio-8080-exec-1死鎖。 分別在日誌中查詢http-nio-8080-exec-9和http-nio-8080-exec-1,可以看到都是BLOCKED狀態;同時可以將問題程式碼位置反饋給開發。

 

方法二:通過jvisualvm檢視

首先是調整遠端監控的引數:
JAVA_OPTS="-Xms650m -Xmx650m -XX:+HeapDumpOnOutOfMemoryError -Dcom.sun.management.jmxremote.port=10086 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.0.110
"

其中-Djava.rmi.server.hostname:遠端連線地址,即程式所在機器地址

jvisualvm連線後如下:

上圖中明顯警告檢測到了死鎖,從圖中線條的顏色也能看出來死鎖的執行緒。

此時點選右上角“執行緒dump”,dump成功後如下,分析方法與jstack結果分許一致。