上一篇博文給大家分享了使用Windbg分析內(nèi)存泄露問題:
Windbg程序調(diào)試系列2-內(nèi)存泄露問題 <https://www.cnblogs.com/tianqing/p/9875667.html>
本篇我們繼續(xù)跟大家分享,如何分析解決線程阻塞問題。
從根本上講,線程阻塞屬于程序Hang的一種,其表現(xiàn)主要有:
1. 隨著請求的增加,線程數(shù)一直增加,可能會把線程池打爆
2. 低CPU使用率(被阻塞后的CPU使用率降低)
3. 請求沒有返回,客戶端一直在等待,直至Timeout。
?那么,從線程狀態(tài)上看,什么是阻塞??一個線程經(jīng)歷的5個狀態(tài),創(chuàng)建,就緒,運行,阻塞,終止。各個狀態(tài)的轉(zhuǎn)換條件如下圖:
上圖中有個阻塞狀態(tài),就是說當線程中調(diào)用某個函數(shù),需要IO請求,或者暫時得不到競爭資源的,操作系統(tǒng)會把該線程阻塞起來,避免浪費CPU資源,等到得到了資源,再變成就緒狀態(tài),等待CPU調(diào)度運行。
線程發(fā)生阻塞的現(xiàn)象就是,進程的線程數(shù)會越來越多!
線程阻塞問題的分析思路:
持續(xù)請求過程中,抓兩個或者三個Dump,看線程增加的速度,每次抓Dump間隔30s或者1分鐘
對比的看每個Dump中:
* 線程池的大小 !threadpool
* 線程的分類和狀態(tài) !threads
* 查看線程阻塞 !syncblk
* 查看阻塞線程的根源線程、線程請求的資源對象 、被阻塞的線程數(shù)
* 查看阻塞根源線程的堆棧~Xs !clrstack
* 分析線程阻塞的原因,改進代碼
1. 查看線程池的大?。?threadpool,有時間間隔兩個Dump對比著看,看線程池的線程數(shù)的增長情況:
2. 查看線程的分類和線程的狀態(tài) !threads,從下圖可以看出,后臺線程一直在增加
3.?查看線程阻塞? !syncblk,也是看這兩個dump,對比著看
我們發(fā)現(xiàn):
第一個Dump中95號線程 阻塞了(1021-1)/2=510個線程
第二個Dump中79號線程 阻塞了(1099-1)/2=549個線程
95號線程獨占的對象資源 00000026ba7c4dc0 (System.Object)
79號線程獨占的對象資源也是00000026ba7c4dc0(System.Object)
兩個線程同時鎖住了同一個資源!00000026ba7c4dc0(System.Object)
此時,線程阻塞問題已經(jīng)確定,接下來,我們要重點分析阻塞的根源線程(持有什么資源不釋放,導致其他線程在等待),95號線程、79號線程
4. 查看阻塞線程的根源線程、線程請求的資源對象 、被阻塞的線程數(shù)
例如 95號線程:
1 查看阻塞根源線程的堆棧 2 ~95s 3 !clrstack
通過線程堆棧,我們在棧頂發(fā)現(xiàn),95號線程,在等待Socket Server返回,具體再等哪個Socket Server?
通過以下命令找出當前線程堆棧上的Socket對象
!dso
這樣我們就定位出95號線程在做什么,在等待什么:
95號線程在等待SocketServer 10.*.*.*:80返回數(shù)據(jù),獨占資源:00000026ba7c4dc0(System.Object)
同時我們通過線程堆??吹搅宋覀冏约旱囊粋€TCP通訊類TCPInvoker, 在創(chuàng)建一個新的TCP連接,TCPInvoker類的代碼需要重點關注,繼續(xù)看!
我們繼續(xù)看79號線程:
1 ~79s 2 !clrstack
通過79號線程的堆棧和阻塞情況可以發(fā)現(xiàn):
79號線程Monitor.Enter(object),在請求資源的獨占鎖:00000026ba7c4dc0(System.Object)
TCPInvoker卡在了GetInvoker方法上。我們需要看看TCPInvoker的代碼了
5. 分析線程阻塞的原因,改進代碼
從如下的代碼中,我們能看到:
95號線程是執(zhí)行到了GetInvoker方法的Create,Create中在等待Socket Server返回,此時如果Socket
Server沒有響應,超時時間默認是5s,會一直持有資源00000026ba7c4dc0(System.Object)不釋放
79號線程也執(zhí)行到了GetInvoker方法,但是在Lock時,等待95號線程釋放資源:00000026ba7c4dc0(System.Object)
隨著請求越來越多,超時+重試連接Socket Server,導致線程阻塞住了。
解決方案:1. 分析Socket Server為什么連不上 2. 優(yōu)化改進TCPInvoker內(nèi)部的業(yè)務邏輯,減少超時和重試時間,減少阻塞的產(chǎn)生幾率。
好了,上面就是這次分享的Windbg調(diào)試線程阻塞問題的細節(jié)和過程,總結(jié)一下:
線程阻塞問題的分析思路:
* 線程池的大小 !threadpool
* 線程的分類和狀態(tài) !threads
* 查看線程阻塞 !syncblk
* 查看阻塞線程的根源線程、線程請求的資源對象 、被阻塞的線程數(shù)
* 查看阻塞根源線程的堆棧~Xs !clrstack
* 分析線程阻塞的原因,改進代碼
周國慶
2018/11/1
?
熱門工具 換一換
感谢您访问我们的网站,您可能还对以下资源感兴趣:
调教肉文小说-国产成本人片免费av-空姐av种子无码-在线观看免费午夜视频-综合久久精品激情-国产成人丝袜视频在线观看软件-大芭区三区四区无码-啊啊好爽啊啊插啊用力啊啊-wanch视频网-国产精品成人a免费观看