Windbg程序调试系列3-线程阻塞问题
上一篇博文給大家分享了使用Windbg分析內存泄露問題:
Windbg程序調試系列2-內存泄露問題
本篇我們繼續跟大家分享,如何分析解決線程阻塞問題。
從根本上講,線程阻塞屬于程序Hang的一種,其表現主要有:
1. 隨著請求的增加,線程數一直增加,可能會把線程池打爆
2. 低CPU使用率(被阻塞后的CPU使用率降低)
3. 請求沒有返回,客戶端一直在等待,直至Timeout。
那么,從線程狀態上看,什么是阻塞?一個線程經歷的5個狀態,創建,就緒,運行,阻塞,終止。各個狀態的轉換條件如下圖:
上圖中有個阻塞狀態,就是說當線程中調用某個函數,需要IO請求,或者暫時得不到競爭資源的,操作系統會把該線程阻塞起來,避免浪費CPU資源,等到得到了資源,再變成就緒狀態,等待CPU調度運行。
線程發生阻塞的現象就是,進程的線程數會越來越多!
線程阻塞問題的分析思路:
持續請求過程中,抓兩個或者三個Dump,看線程增加的速度,每次抓Dump間隔30s或者1分鐘
對比的看每個Dump中:
線程池的大小 !threadpool
線程的分類和狀態 !threads
查看線程阻塞 !syncblk
查看阻塞線程的根源線程、線程請求的資源對象 、被阻塞的線程數
查看阻塞根源線程的堆棧~Xs !clrstack
分析線程阻塞的原因,改進代碼
1. 查看線程池的大小:!threadpool,有時間間隔兩個Dump對比著看,看線程池的線程數的增長情況:
2. 查看線程的分類和線程的狀態 !threads,從下圖可以看出,后臺線程一直在增加
3.查看線程阻塞 !syncblk,也是看這兩個dump,對比著看
我們發現:
第一個Dump中95號線程 阻塞了(1021-1)/2=510個線程
第二個Dump中79號線程 阻塞了(1099-1)/2=549個線程
95號線程獨占的對象資源 00000026ba7c4dc0 (System.Object)
79號線程獨占的對象資源也是00000026ba7c4dc0(System.Object)
兩個線程同時鎖住了同一個資源!00000026ba7c4dc0(System.Object)
此時,線程阻塞問題已經確定,接下來,我們要重點分析阻塞的根源線程(持有什么資源不釋放,導致其他線程在等待),95號線程、79號線程
4. 查看阻塞線程的根源線程、線程請求的資源對象 、被阻塞的線程數
例如 95號線程:
1 查看阻塞根源線程的堆棧 2 ~95s 3 !clrstack
通過線程堆棧,我們在棧頂發現,95號線程,在等待Socket Server返回,具體再等哪個Socket Server?
通過以下命令找出當前線程堆棧上的Socket對象
!dso
這樣我們就定位出95號線程在做什么,在等待什么:
95號線程在等待SocketServer 10.*.*.*:80返回數據,獨占資源:00000026ba7c4dc0(System.Object)
同時我們通過線程堆棧看到了我們自己的一個TCP通訊類TCPInvoker, 在創建一個新的TCP連接,TCPInvoker類的代碼需要重點關注,繼續看!
我們繼續看79號線程:
1 ~79s 2 !clrstack
通過79號線程的堆棧和阻塞情況可以發現:
79號線程Monitor.Enter(object),在請求資源的獨占鎖:00000026ba7c4dc0(System.Object)
TCPInvoker卡在了GetInvoker方法上。我們需要看看TCPInvoker的代碼了
5. 分析線程阻塞的原因,改進代碼
從如下的代碼中,我們能看到:
95號線程是執行到了GetInvoker方法的Create,Create中在等待Socket Server返回,此時如果Socket Server沒有響應,超時時間默認是5s,會一直持有資源00000026ba7c4dc0(System.Object)不釋放
79號線程也執行到了GetInvoker方法,但是在Lock時,等待95號線程釋放資源:00000026ba7c4dc0(System.Object)
隨著請求越來越多,超時+重試連接Socket Server,導致線程阻塞住了。
解決方案:1. 分析Socket Server為什么連不上 2. 優化改進TCPInvoker內部的業務邏輯,減少超時和重試時間,減少阻塞的產生幾率。
好了,上面就是這次分享的Windbg調試線程阻塞問題的細節和過程,總結一下:
線程阻塞問題的分析思路:
線程池的大小 !threadpool
線程的分類和狀態 !threads
查看線程阻塞 !syncblk
查看阻塞線程的根源線程、線程請求的資源對象 、被阻塞的線程數
查看阻塞根源線程的堆棧~Xs !clrstack
分析線程阻塞的原因,改進代碼
**************************轉摘:https://www.cnblogs.com/tianqing/p/9887309.html
總結
以上是生活随笔為你收集整理的Windbg程序调试系列3-线程阻塞问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何计算教师工龄?工龄和教龄的区别
- 下一篇: 【算法分析】实验 1. 基于贪心的会议安