效能問題之執行緒死鎖
阿新 • • 發佈:2022-04-14
定義
執行緒死鎖就是有兩個執行緒,一個執行緒鎖住了資源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由上可知:執行緒http-nio-8080-exec-9和http-nio-8080-exec-1死鎖。 分別在日誌中查詢http-nio-8080-exec-9和http-nio-8080-exec-1,可以看到都是BLOCKED狀態;同時可以將問題程式碼位置反饋給開發。<0x00000000e6a31c88> - locked <0x00000000e6a31c68>
方法二:通過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結果分許一致。