cpu线程_记w3wp占用CPU过高解决过程Dictionary线程安全
項(xiàng)目上線以來一直存在一個(gè)比較揪心的問題,和一個(gè)沒有信心處理的BUG,那就是在應(yīng)用程序啟動(dòng)時(shí)有可能會(huì)導(dǎo)致cpu跑滿99%或持續(xù)在一個(gè)值如50%左右,這樣一來對(duì)服務(wù)器的壓力是非常大的,經(jīng)常出現(xiàn)服務(wù)器無法遠(yuǎn)程的狀態(tài),唯有通過PowerShell殺掉對(duì)應(yīng)的w3wp進(jìn)程才可以解決這個(gè)問題。
為什么沒有信心處理這個(gè)問題
原因非常簡(jiǎn)單,這個(gè)問題是間歇性的,不容易重現(xiàn)的,只會(huì)在項(xiàng)目啟動(dòng)時(shí)有一定的可能性會(huì)發(fā)生CPU跑滿的問題。
所有可以重現(xiàn)的BUG的處理都不會(huì)太難,而類似這種無法重現(xiàn)的BUG是最讓人頭疼的,因?yàn)樗鼰o影無蹤,令人難以尋跡。
如何處理這個(gè)問題?
1.一開始采用猜的辦法,去項(xiàng)目中找while、lock等關(guān)鍵詞,這樣無異于大海撈針,而且不嚴(yán)謹(jǐn)?shù)男薷倪€會(huì)導(dǎo)致其他更為嚴(yán)重的問題產(chǎn)生,很快這個(gè)方案在搜尋過一遍后被放棄了。
2.后來記得有用過WinDbg解決過電腦藍(lán)屏的問題,就猜想是否可以抓取對(duì)應(yīng)w3wp進(jìn)程的dump進(jìn)行分析。
使用WinDbg查找線索
1.由于服務(wù)器是2008R2抓取dump就變得異常簡(jiǎn)單。
2.使用WinDbg
load SOS.dll后查看線程信息。
發(fā)現(xiàn)有7個(gè)線程比較耗時(shí),這時(shí)候心想我用的線程也是7個(gè),這時(shí)候內(nèi)心無比的激動(dòng)。
切換到21線程,查看堆棧信息后發(fā)現(xiàn)
在Dictionary的Insert時(shí)堵塞了,這時(shí)候查看其它占時(shí)很長(zhǎng)的線程狀態(tài),也不外乎是這里堵塞了。
Dictionary中的Insert方法真的會(huì)堵塞嗎?
寫下如下測(cè)試代碼后運(yùn)行了幾次
發(fā)現(xiàn)真的在有些時(shí)候cpu會(huì)占得非常高有時(shí)候又正常。
那么問題也就明朗了,解決它也變得非常容易,找到GetRoutes代碼,原先是這么實(shí)現(xiàn)的
BundleTable.Bundles內(nèi)部維護(hù)了一個(gè)靜態(tài)字典表,那么問題就呼之欲出了,對(duì)這段代碼加鎖。
修改后的代碼
觀測(cè)了一段時(shí)間后,問題也確實(shí)解決了。
Dictionary中的Insert為什么會(huì)堵塞
我知道Dictionary不是一個(gè)線程安全的類型,但我原本以為Dictionary在非線程安全方式下訪問時(shí)數(shù)據(jù)會(huì)錯(cuò)亂,而不會(huì)堵塞或者死鎖,而這次的這個(gè)問題讓我感覺到訝異,為什么Add一個(gè)項(xiàng)目會(huì)造成堵塞?
反編譯Dictionary的源碼后發(fā)現(xiàn)異常的復(fù)雜,也沒有細(xì)究,所以下面的一段描述大家抱有自己的想法去閱讀,可能是錯(cuò)的也可能是對(duì)的。
上面是我認(rèn)為存在問題的地方,當(dāng)一個(gè)線程執(zhí)行過Initialize后buckets數(shù)組的值被修改,而第二個(gè)線程同時(shí)進(jìn)入了Initialize方法,那么第一個(gè)線程所維護(hù)的值被破壞,造成在算法環(huán)節(jié)出現(xiàn)了死循環(huán),這也可以說明了為什么cpu有時(shí)候是50%有時(shí)候是99%的問題。
當(dāng)前有多少個(gè)線程發(fā)生了這種狀態(tài),如果發(fā)生這種狀態(tài)的線程越多則代表cpu占用越多。
寫在最后
由于一開始不會(huì)使用WinDbg找了某大神幫忙解決問題,巧合的是兩人推測(cè)出的問題在此相撞,
總結(jié)
以上是生活随笔為你收集整理的cpu线程_记w3wp占用CPU过高解决过程Dictionary线程安全的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 搜狗浏览器收藏夹在哪_是时候换个快速安全
- 下一篇: pcie固态硬盘_主板2个M. 2接口,