精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

又一起.NET程序掛死, 用 Windbg 抽絲剝繭式的真實案例分析

開發 前端
為了理解為啥底層會創建那么多線程,我特意還查了下串口類 SerialPort,說串口發送方送過來的數據,接收方可以主動接收,可以被動接收,被動就是這種 事件模式,接收方收到發送方送來的數據時,操作系統會讓 CLR 通過 Thread 來處理這段回調事件,所以從卦象上看就是典型的接收方處理能力不足造成的大量 lock 等待。

 [[394026]]

本文轉載自微信公眾號「一線碼農聊技術」,作者一線碼農聊技術。轉載本文請聯系一線碼農聊技術公眾號。

一:背景

1. 講故事

前天有位粉絲朋友在后臺留言讓我幫忙看看他的 Winform程序 UI無響應 + 410線程 到底是啥情況,如下圖:

說實話,能看到這些真實案例我是特別喜歡的 ,就像醫生看病,光停留在理論和那些 demo 上,那是沒有前途的,如果有朋友在這塊搞不定的話,我可以免費幫你解讀 dump,再附送一篇博客詳述。

好了,言歸正傳,既然粉絲朋友已經提到了高達 410 線程,我本能反應就是要么高負載,要么野線程,后者大多是無數新出現的線程卡在某個鎖上。

WinForm 出現高負載的情況,我至今還是沒遇到??????,如果說卡在某個鎖上,基本都屬于這類,有了這個先入為主的思路,接下來就可以祭出 windbg 一探究竟了。

二:windbg 分析

1. 查找 CLR 同步塊表

十個人用鎖,八個人會用 lock, 所以先用 !syncblk 看看程序的鎖情況。

  1. 0:000> !syncblk 
  2. Index         SyncBlock MonitorHeld Recursion Owning Thread Info          SyncBlock Owner 
  3.    76   070e5fa4           67         1 17367570 15e8 218   03e6dd68 System.IO.Ports.SerialStream 
  4. ----------------------------- 
  5. Total           789 
  6. CCW             39 
  7. RCW             2 
  8. ComClassFactory 1 
  9. Free            535 

我去,從卦象上來看情況很不好,我來簡單分析下。

  • MonitorHeld = 67

這個 67 表示當前有 1 個線程持有鎖,有 33 個線程在等待鎖,肯定有朋友想問怎么算的?很簡單:當一個線程持有了鎖的時候 MonitorHeld+1 ,當一個線程在等待鎖的時候 MonitorHeld+2 ,所以表達式就是: 67= [1 + 66=(33*2)]。

  • Owning Thread Info = 17367570 15e8 218

上面三個信息都表示當前持有線程,可以看最后的 218,它是 windbg 映射出來的線程ID,如果不信的話,可以用 !t 來一探究竟。

  1. 0:000> !t 
  2. ThreadCount:      315 
  3. UnstartedThread:  0 
  4. BackgroundThread: 302 
  5. PendingThread:    0 
  6. DeadThread:       0 
  7. Hosted Runtime:   no 
  8.                                                                          Lock   
  9.        ID OSID ThreadOBJ    State GC Mode     GC Alloc Context  Domain   Count Apt Exception 
  10.    0    1  c64 00cc3de0     24220 Preemptive  042E1884:00000000 00cbc0a0 0     STA  
  11.  214  240 1398 16702b90   1029220 Preemptive  00000000:00000000 00cbc0a0 0     MTA (Threadpool Worker)  
  12.  215  323  b5c 12ab7260   1029220 Preemptive  00000000:00000000 00cbc0a0 0     MTA (Threadpool Worker)  
  13.  216  290 1858 16c21c98   1029220 Preemptive  00000000:00000000 00cbc0a0 0     MTA (Threadpool Worker)  
  14.  218  117 15e8 17367570   1029220 Preemptive  00000000:00000000 00cbc0a0 1     MTA (Threadpool Worker)  
  15.  ... 

對,就是 218 這個罪魁禍首在持有了鎖,導致 33 個線程在無辜的等待它。。。

  • SyncBlock Owner = System.IO.Ports.SerialStream

也許你會好奇,到底 lock 持有的是哪一個對象呢?從 SyncBlock Owner 上看就是 SerialStream, ????,原來老兄在玩串口編碼,我先膜拜一下。

2. 查看線程棧

知道是 218 惹的禍,接下來可以看看它的線程棧,到底都在干什么?

關于上面的調用棧,可能有些朋友看不明白,我畫了一張簡圖:

從圖中看,來自于 ThreadPool 的線程在用戶自定義的 DataReceived 方法上卡住了,為了方便我就用 !DumpIL 看看這個方法的 IL 代碼。

  1. 0:218> !name2ee *!xxx.TYAComYB.DataReceived 
  2. Module:      03b10cc4 
  3. Assembly:    YKit.dll 
  4. Token:       06000108 
  5. MethodDesc:  08533584 
  6. Name:        xxx.TYAComYB.DataReceived(System.Object, System.IO.Ports.SerialDataReceivedEventArgs) 
  7. JITTED Code Address: 08644dc0 
  8.  
  9. 0:218> !dumpil 08533584 
  10. ilAddr = 05dc2dd8 
  11. IL_0000: nop  
  12. IL_0001: nop  
  13. IL_0002: nop  
  14. IL_0003: ret  

這代碼居然藏了鉤子,用 !dumpil 居然看不到代碼,難怪在線程棧上看到了類似混淆的方法:xxx.TYAComYB.EYLlXL2bKH(),不過看反匯編是沒有問題的,簡化如下:

  1. 0:218> !U /d 08644edf 
  2. 08644ddd e86edaffff      call    08642850 (xxxx.com.ComPort.get_isOpen(), mdToken: 060004b6) 
  3. 08644df4 e807deffff      call    08642c00 (xxxx.YBComParam.get_DataPacketLen(), mdToken: 0600010c) 
  4. 08644dfb b92a3e136e      mov     ecx,offset mscorlib_ni!System.GC.ReRegisterForFinalize(System.Object) <PERF> (mscorlib_ni+0x3e2a) (6e133e2a) 
  5. 08644e00 e80fd460f8      call    00c52214 (JitHelp: CORINFO_HELP_NEWARR_1_VC) 
  6. 08644e15 e8e6ddffff      call    08642c00 (xxx.YBComParam.get_DataPacketLen(), mdToken: 0600010c) 
  7. 08644e22 e8edac4d68      call    System_ni+0x13fb14 (70b1fb14) (System.IO.Ports.SerialPort.Read(Byte[], Int32, Int32), mdToken: 06004173) 
  8. 08644e2e ff153836b103    call    dword ptr ds:[3B13638h] (xxxx.LogKit.WriteLine(System.Exception), mdToken: 06000183) 
  9. 08644e59 e8a2ddffff      call    08642c00 (xxxx.YBComParam.get_DataPacketLen(), mdToken: 0600010c) 
  10. 08644e64 ff1580355308    call    dword ptr ds:[8533580h] (xxxx.TYAComYB.EYLlXL2bKH(), mdToken: 06000107) 
  11. 08644e9b ff15a4265308    call    dword ptr ds:[85326A4h] (xxxx.YBComParam.get_DataPacketStart(), mdToken: 0600010e) 
  12. 08644ea8 e837e34e66      call    mscorlib_ni!System.Convert.ToByte(System.String, Int32) (6eb331e4) 
  13. 08644ed9 ff1580355308    call    dword ptr ds:[8533580h] (xxxx.TYAComYB.EYLlXL2bKH(), mdToken: 06000107) 

反正做的事情挺多,我就懶得分析了。

接下來看看那 33 個線程怎么就卡在 SerialStream 上呢?可以用 ~*e !clrstack 掃一下所有的 threads,抽幾個看看。

  1. 0:218> ~*e !clrstack 
  2. OS Thread Id: 0xc64 (0) 
  3. Child SP       IP Call Site 
  4. OS Thread Id: 0x13d8 (330) 
  5. Child SP       IP Call Site 
  6. 1b1aec90 77c8016d [GCFrame: 1b1aec90]  
  7. 1b1aee30 77c8016d [GCFrame: 1b1aee30]  
  8. 1b1aede0 77c8016d [HelperMethodFrame: 1b1aede0] System.Threading.Monitor.ReliableEnter(System.Object, Boolean ByRef) 
  9. 1b1aee70 710d6b54 System.IO.Ports.SerialPort.CatchReceivedEvents(System.Object, System.IO.Ports.SerialDataReceivedEventArgs) 
  10. 1b1aeeac 710d9520 System.IO.Ports.SerialStream+EventLoopRunner.CallReceiveEvents(System.Object) 
  11. 1b1aeec0 6e45e356 System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Object) 
  12. 1b1aeec8 6e43da07 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 
  13. 1b1aef34 6e43d956 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 
  14. 1b1aef48 6e45f120 System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() 
  15. 1b1aef5c 6e45e929 System.Threading.ThreadPoolWorkQueue.Dispatch() 
  16. 1b1aefac 6e45e7d5 System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() 
  17. 1b1af1d4 71382552 [DebuggerU2MCatchHandlerFrame: 1b1af1d4]  

我去,居然都卡在 System.IO.Ports.SerialPort.CatchReceivedEvents 這里了,而且還是 framework 提供的,這就很困惑了。

3. 分析 SerialPort 源碼

要想看 SerialPort 類的源碼,可以用 ILSpy,如下圖所示:

看到這里,再結合我剛才畫的圖,思路是不是就清晰多了,究其原因就是 dataReceived(this, e); 觸發的用戶回調函數遲遲得不到結束,導致底層大量的線程在 lock 處等待。

三:總結

為了理解為啥底層會創建那么多線程,我特意還查了下串口類 SerialPort,說串口發送方送過來的數據,接收方可以主動接收,可以被動接收,被動就是這種 事件模式,接收方收到發送方送來的數據時,操作系統會讓 CLR 通過 Thread 來處理這段回調事件,所以從卦象上看就是典型的接收方處理能力不足造成的大量 lock 等待。

大概提兩點優化措施:

  • 提升 xxx.TYAComYB.DataReceived 方法中業務邏輯的處理能力。
  • 增加蓄水池,讓底層的 lock (serialStream) 盡快得到釋放。

 

 

責任編輯:武曉燕 來源: 一線碼農聊技術
相關推薦

2015-06-09 11:13:18

2021-06-16 07:56:21

Redis分布式

2021-06-11 18:27:10

LinuxLinux內核

2022-07-11 11:28:45

數據分析業務消費

2024-04-01 00:07:20

LinuxeBPF源碼

2022-07-05 21:31:21

索引SQL分庫分表

2022-01-17 17:55:29

Python變量交換開發

2020-05-06 08:01:39

黑客惡意攻擊網絡安全

2024-01-03 16:39:07

2025-05-12 08:27:25

2017-09-15 09:18:27

JavaSQLDBA

2022-04-01 15:18:42

Web 框架網絡通信

2018-09-13 15:21:36

CTO訓練營

2020-06-11 16:15:25

Java線程池代碼

2012-12-17 10:14:47

Wi-Fiwifi無線網絡

2023-06-27 13:47:00

分布式事務本地事務

2020-02-26 08:00:20

惡意刪庫拘留

2024-11-15 16:52:23

C#棧邊界?;?/a>

2015-12-28 16:09:20

物聯網市場

2025-06-18 08:00:56

點贊
收藏

51CTO技術棧公眾號

亚洲欧美日韩人成在线播放| 精品制服美女久久| 精品性高朝久久久久久久| 99色精品视频| 网友自拍视频在线| 懂色av一区二区三区免费观看| 欧美一区亚洲一区| 国产精品精品软件男同| 国产精品久久久久久久久久白浆 | 午夜影院在线播放| 中文字幕在线视频一区| 激情小说网站亚洲综合网| 亚洲中文无码av在线| 欧美日韩1区| 国产一区二区激情| 久久免费精品国产| av成人在线观看| 红桃视频成人在线观看| 在线观看福利一区| 视频一区二区三区国产 | 91精品视频观看| √资源天堂中文在线| 亚洲一区色图| 有码中文亚洲精品| 在线免费观看a级片| 日本在线一区二区| 91高清在线观看| 久久亚洲中文字幕无码| 超碰在线caoporn| 中国色在线观看另类| 精品日产一区2区三区黄免费| av网站在线免费看| 免费人成精品欧美精品| 日韩暖暖在线视频| 免费看日韩毛片| 欧美日韩 国产精品| 久久成人在线视频| 神马久久精品综合| 久久福利影院| 在线视频一区二区| 国产18无套直看片| 欧美猛男同性videos| 亚洲精品视频播放| 亚洲av无码一区二区三区观看| 亚洲视频一起| 日韩午夜小视频| 深爱五月综合网| 99久久久国产| 欧美一区二区三区免费| 五月天激情播播| 国产精品黄色片| 精品1区2区3区| 午夜两性免费视频| 黑人一区二区三区| 欧美日韩成人一区| 毛片毛片毛片毛| 成人av在线播放| 91精品一区二区三区久久久久久| 日日干日日操日日射| 欧美成人家庭影院| 欧美一区日本一区韩国一区| 一级黄色高清视频| 盗摄牛牛av影视一区二区| 亚洲国产成人爱av在线播放| 草草地址线路①屁屁影院成人| 欧美毛片免费观看| 精品一区二区三区四区| 久久久久久久久久久久| 精品久久91| 这里只有精品在线观看| 天天天天天天天天操| 黄色成人在线网址| 人九九综合九九宗合| 国产精品xxxxxx| 激情文学综合丁香| 国产精品国产一区二区| 神马电影在线观看| 国产精品视频在线看| 日韩亚洲欧美一区二区| 激情黄产视频在线免费观看| 91福利资源站| 在线视频观看一区二区| 超碰一区二区三区| 亚洲欧美激情视频| 快灬快灬一下爽蜜桃在线观看| 午夜av一区| 91chinesevideo永久地址| 亚洲成人av网址| 国产精品综合av一区二区国产馆| 国产在线播放一区二区| 91在线不卡| 午夜精品一区二区三区免费视频| 中文字幕永久视频| 日韩免费高清视频网站| 亚洲欧美自拍一区| 久久av高潮av无码av喷吹| 亚洲尤物影院| 99久re热视频这里只有精品6| 香蕉视频免费看| 亚洲天天做日日做天天谢日日欢 | 亚洲色图官网| 欧美一区二区在线视频| 五级黄高潮片90分钟视频| 99久久夜色精品国产亚洲96 | 久久精品超碰| 亚洲国产高清高潮精品美女| 很污很黄的网站| 中文亚洲免费| 91在线无精精品一区二区| 九九在线视频| 亚洲福利国产精品| 亚洲综合在线一区二区| blacked蜜桃精品一区| 97香蕉久久夜色精品国产| 一区二区日韩在线观看| 久久久久久久久久久黄色 | 麻豆91蜜桃| 97caopor国产在线视频| 欧美性xxxxxx少妇| 亚洲国产无码精品| 亚洲经典在线看| 91免费版网站在线观看| av网站无病毒在线| 一本色道久久综合狠狠躁的推荐 | 久久香蕉网站| 久久91精品国产| 国产麻豆精品一区| 国产精品色婷婷久久58| 日本黄色三级大片| 欧洲亚洲成人| 97在线视频免费| 亚洲乱色熟女一区二区三区| 亚洲欧美激情视频在线观看一区二区三区 | 丁香花五月婷婷| 老鸭窝91久久精品色噜噜导演| 国产精品99久久久久久久| 宅男在线观看免费高清网站| 欧美日韩成人综合| 可以免费看av的网址| 美国十次了思思久久精品导航| 欧美一卡2卡3卡4卡无卡免费观看水多多| 欧美人与性动交α欧美精品图片| 欧美肥妇毛茸茸| 四虎884aa成人精品| 美国十次了思思久久精品导航| 亚洲成色www久久网站| 日韩一区二区三区免费视频| 怡红院精品视频| 在线观看中文字幕2021| 综合自拍亚洲综合图不卡区| 精品久久久99| 欧美一区二区| 国产精品v欧美精品v日韩| 青草在线视频| 日韩精品在线观看一区| 久久国产视频一区| 国产欧美日韩亚州综合 | 试看120秒一区二区三区| 欧美区二区三区| 国模无码一区二区三区| 午夜不卡av在线| 永久免费毛片在线观看| 久久99在线观看| 中文字幕人妻熟女人妻洋洋| 97久久综合区小说区图片区| 久久久亚洲欧洲日产国码aⅴ| 手机看片一区二区三区| 91福利在线播放| 神马久久精品综合| av一区二区三区四区| 欧美牲交a欧美牲交| 欧洲杯足球赛直播| 91久久久久久久久| 国内在线免费视频| 亚洲免费av片| 夜夜躁狠狠躁日日躁av| 亚洲精品国产视频| 中文字幕日韩三级片| 日韩av成人高清| 日韩精品手机在线观看| 丝袜美腿一区二区三区动态图| 国产精品久久久久久中文字| 91在线中文| 日韩精品视频免费在线观看| 在线观看日批视频| 亚洲成a天堂v人片| 蜜桃av免费在线观看| 国产91丝袜在线播放九色| 日韩av在线综合| 亚洲国产一区二区三区在线播放| 精品欧美一区二区精品久久| 日本亚洲欧洲无免费码在线| 亚洲18私人小影院| 快射视频在线观看| 亚洲美女在线看| 精品国产亚洲av麻豆| 91黄色激情网站| 精品无码人妻一区二区三区品| 国产日韩在线不卡| 波多野结衣办公室双飞| 免费观看在线色综合| 精品久久久久久无码中文野结衣| 成人情趣视频网站| 久久综合久久久| 日韩激情欧美| 国产中文字幕91| 美女福利一区二区三区| 久久99国产精品久久久久久久久| 国产日韩精品在线看| 亚洲第一av网| 国产欧美久久久精品免费| 日本高清不卡视频| 日韩精品视频免费播放| 亚洲柠檬福利资源导航| 在线观看亚洲大片短视频| 91老师片黄在线观看| 古装做爰无遮挡三级聊斋艳谭| 日本亚洲视频在线| 2022亚洲天堂| 在线观看视频免费一区二区三区| 一区一区视频| 欧美三级伦理在线| 欧美极品jizzhd欧美| 高潮久久久久久久久久久久久久 | 乱子伦视频在线看| 亚洲黄色成人| 精品国偷自产一区二区三区| 亚洲激情久久| 伊人色综合影院| 色999国产精品| 天天综合狠狠精品| 欧美日韩精品在线一区| 欧美一区1区三区3区公司| 色先锋久久影院av| 精品日本一区二区| 日韩精品免费一区二区三区竹菊| 国产成人一区二区三区免费看| 激情视频亚洲| 91网站在线免费观看| 四虎影视精品永久在线观看| 国产精品女人网站| 麻豆久久久久| 成人免费观看a| 豆花视频一区| 91精品国产91久久久久青草| 精品三级国产| 99久久精品无码一区二区毛片| 欧洲大片精品免费永久看nba| 成人免费xxxxx在线观看| 亚洲免费一区| 4444kk亚洲人成电影在线| 中文一区二区三区四区| 国产在线一区二区三区播放| 欧美绝顶高潮抽搐喷水合集| 欧美日韩另类综合| 成人情趣视频| 400部精品国偷自产在线观看| 欧美成人久久| 欧美视频在线观看网站| 欧美亚洲一区二区三区| 91香蕉视频污版| 韩国一区二区在线观看| 精品国产免费久久久久久婷婷| 成人激情文学综合网| 毛片网站免费观看| 中文子幕无线码一区tr| 粉嫩av性色av蜜臀av网站| 亚洲一二三四区不卡| 男人午夜免费视频| 欧美日韩中文字幕一区二区| 国产aⅴ爽av久久久久成人| 精品国产精品一区二区夜夜嗨| 亚洲 小说区 图片区 都市| 亚洲人成网站在线播| 国产在线1区| 亚洲18私人小影院| 日韩国产一二三区| 成人自拍视频网站| 国产午夜一区| 超级碰在线观看| 国产精品试看| 热久久久久久久久| av电影天堂一区二区在线观看| 人妻aⅴ无码一区二区三区| 亚洲欧美区自拍先锋| 国产又黄又猛又粗又爽| 8v天堂国产在线一区二区| 少妇高潮久久久| 色妞色视频一区二区三区四区| 国产蜜臀在线| 国产精品视频一区国模私拍| 538任你躁精品视频网免费| 欧美连裤袜在线视频| 综合激情婷婷| 五月天婷婷激情视频| 成人网页在线观看| 欧美特黄一级片| 日韩欧美大尺度| 性生活免费网站| 色综合伊人色综合网| 精精国产xxxx视频在线播放| 国产日韩欧美日韩| 亚洲最好看的视频| www.国产二区| 久久69国产一区二区蜜臀| 久久亚洲AV成人无码国产野外| 最新成人av在线| 日韩久久久久久久久久| 日韩黄色av网站| 成人在线直播| 国产精品网站入口| 一本久久青青| 成人免费aaa| 成人午夜私人影院| 男人与禽猛交狂配| 欧美性感一类影片在线播放| 日本福利片在线| 午夜精品一区二区三区在线播放| 国产精品麻豆| 杨幂一区欧美专区| 日产欧产美韩系列久久99| 爱爱免费小视频| 午夜精品福利久久久| 性欧美8khd高清极品| 久久亚洲成人精品| **日韩最新| 中文字幕中文字幕99| 日韩av在线播放中文字幕| 在线不卡av电影| 欧美日韩在线看| 亚洲欧美日韩免费| 97在线视频免费播放| 91精品导航| 久久这里只有精品18| 成人一区二区在线观看| 久操免费在线视频| 精品久久久久久久人人人人传媒| 羞羞视频在线免费国产| 91在线视频一区| 一本一道久久a久久精品蜜桃| 国产精品v日韩精品v在线观看| 国产日韩精品视频一区| 羞羞色院91蜜桃| 中文字幕一区日韩电影| 亚洲综合伊人| 国产免费xxx| 风间由美性色一区二区三区| 久久免费在线观看视频| 亚洲国产成人久久| 综合另类专区| 水蜜桃亚洲精品| 精品一区二区三区欧美| 内射一区二区三区| 精品久久久网站| 国产色播av在线| 欧美在线一二三区| 久久www免费人成看片高清| 欧美卡一卡二卡三| 亚洲成人a级网| 日韩pacopacomama| 亚洲欧洲一区二区| 国产精品综合一区二区三区| www.99re7.com| 亚洲精品中文字| 欧美成人一二区| 草草视频在线免费观看| 久久综合九色综合欧美就去吻| 中文字幕精品视频在线观看| www.亚洲人.com| 成人香蕉社区| 一本久道综合色婷婷五月| 亚洲欧洲另类国产综合| 亚洲精品字幕在线观看| 国产成人精品999| 欧美一区二区三区久久精品| 成人区人妻精品一区二| 色天天综合久久久久综合片| 国产福利在线播放麻豆| 国产日韩一区二区三区| 日本大胆欧美人术艺术动态| 欧美又粗又大又长| 亚洲精品在线看| 日韩精品一区二区三区中文在线| 欧美成人xxxxx| 中文字幕一区av| 天堂中文在线看| 国产综合久久久久久| 一区二区三区四区五区精品视频| av手机在线播放| 日韩精品一区二区在线观看| 欧美亚洲大片| 丁香婷婷综合激情| 中文久久乱码一区二区| 天堂在线资源库| 91久久国产婷婷一区二区| 欧美一级视频| 免费麻豆国产一区二区三区四区| 国产亚洲视频中文字幕视频| 国产成人澳门| 超碰中文字幕在线观看|