一:背景

1. 讲故事

前天有位粉丝朋友在后台留言让我帮忙看看他的 Winform程序 UI无响应 + 410线程 到底是啥情况,如下图:

说实话,能看到这些真实案例我是特别喜欢的 ,就像医生看病,光停留在理论和那些 demo 上,那是没有前途的,如果有朋友在这块搞不定的话,我可以免费帮你解读 dump,再附送一篇博客详述。

好了,言归正传,既然粉丝朋友已经提到了高达 410 线程,我本能反应就是要么高负载,要么野线程,后者大多是无数新出现的线程卡在某个锁上。

WinForm 出现高负载的情况,我至今还是没遇到,如果说卡在某个锁上,基本都属于这类,有了这个先入为主的思路,接下来就可以祭出 windbg 一探究竟了。

二: windbg 分析

1. 查找 CLR 同步块表

十个人用锁,八个人会用 lock, 所以先用 !syncblk 看看程序的锁情况。


0:000> !syncblk
Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner
76 070e5fa4 67 1 17367570 15e8 218 03e6dd68 System.IO.Ports.SerialStream
-----------------------------
Total 789
CCW 39
RCW 2
ComClassFactory 1
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 来一探究竟。


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

对,就是 218 这个罪魁祸首在持有了锁,导致 33 个线程在无辜的等待它。。。

  • SyncBlock Owner = System.IO.Ports.SerialStream

也许你会好奇,到底 lock 持有的是哪一个对象呢?从 SyncBlock Owner 上看就是 SerialStream

最新文章

  1. jq.validate 自定义验证两个日期
  2. C++ 虚函数表解析
  3. jquery实现简单瀑布流布局
  4. 8-06循环结构WHILE
  5. javascript版快速排序和冒泡排序
  6. display:inline-block 和float:left 的区别
  7. jQuery 的属性
  8. Windows Azure Cloud Service (42) 使用Azure In-Role Cache缓存(1)Co-located Role
  9. Arrya数组添加过滤条件
  10. .NET微信通过授权获取用户的基本信息
  11. Java开发中的23种设计模式(转)
  12. MetadataType的使用,MVC的Model层数据验证
  13. 【转】使用XCODE 的SOURCE CONTROL 做版本控制 (1)
  14. Codevs 1081 线段树练习 2
  15. Unity 改变类模板-为你的类添加一个命名空间
  16. Log4j2 简明教程
  17. 在ExpressJS中设置二级域名跨域共享Cookie
  18. Chapter 5 Blood Type——8
  19. SQL SERVER启动步骤
  20. vue中嵌套页面(iframe)

热门文章

  1. pycharm + git+gitlab的可视化界面操作
  2. vue_webpack
  3. Why GraphQL? 6个问题
  4. 字符串拼接出现null的问题
  5. 微信小程序优化:实现picker组件中input输入框禁止输入,而只能通过picker组件选择日期
  6. Redis与Spring Data Redis
  7. oracle ORA-00257
  8. 【转载】几张图轻松理解String.intern()
  9. POJ-3259(最短路+Bellman-Ford算法判负圈)
  10. PCA——主成分分析