一:背景1.讲故事【第一篇 TTD 专题 :C# 那些短命线程都在干什么?】在分析的众多dump中,经常会遇到各种奇葩的问题,仅通过dump这种快照形式还是有很多问题搞不定,而通过 perfview 这种粒度又太粗,很难找到问题之所在,真的很头疼,比如本篇的 短命线程
问题,参考图如下:
文章插图
我们在 t2 时刻抓取的dump对查看
短命线程
毫无帮助,我根本就不知道这个线程生前执行了什么代码,为什么这么短命,还就因为这样的短命让 线程池 的线程暴增 。为了能尽最大努力解决此类问题,武器库中还得再充实一下,比如本系列要聊的
Time Travel Debug
,即时间旅行调试 。二: Time Travel Debug1. 什么是 时间旅行调试如果说 dump 是程序的一张照片,那 TTD 就是程序的一个短视频,很显然短视频的信息量远大于一张照片,因为视频记录着疑难杂症的前因后果,参考价值巨大,简直就是银弹般的存在 。
三:案例演示1. 参考代码这是我曾经遇到的一个真实案例,在没有 TTD 的协助下最终也艰难的找到了问题,但如果有 TTD 的协助简直就可以秒杀,为了方便说明,先上一个测试代码 。
internal class Program{static void Main(string[] args){for (int i = 0; i < 200; i++){Task.Run(() =>{Test();});}Console.ReadLine();}public static int index = 1;static void Test(){Thread.Sleep(1000);var i = 10;var j = 20;var sum = i + j;Console.WriteLine($"i={index++},sum={sum}");}}
程序跑完之后,我们抓一个dump文件,输出如下 。0:000> !tThreadCount:20UnstartedThread:0BackgroundThread: 7PendingThread:0DeadThread:13Hosted Runtime:noLock DBGIDOSID ThreadOBJState GC ModeGC Alloc ContextDomainCount Apt Exception0112f8 00C4AF2080030220 Preemptive03C3FFAC:03C40000 00c462f8 -00001 Ukn626a70 00C5BBD82b220 Preemptive03C521B8:03C53FE8 00c462f8 -00001 MTA (Finalizer)XXXX40 00C9FEB01039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)756694 00CA0990302b220 Preemptive03C40314:03C41FE8 00c462f8 -00001 MTA (Threadpool Worker)XXXX60 00CB53B81039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)XXXX70 00CB59581039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)XXXX80 00CB43381039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)XXXX90 00CB4C581039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)XXXX100 088792781039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)8115d10 08879E90102b220 Preemptive03C2AC2C:03C2BFE8 00c462f8 -00001 MTA (Threadpool Worker)XXXX120 0887D1F81039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)XXXX130 0887C0D81039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)XXXX140 0887AB701039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)XXXX150 0887B4001039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)XXXX160 0887D6401039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)XXXX170 0887A7281039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)9185658 0887C520102b220 Preemptive03C46684:03C47FE8 00c462f8 -00001 MTA (Threadpool Worker)1019564 0887C968102b220 Preemptive03C4A664:03C4BFE8 00c462f8 -00001 MTA (Threadpool Worker)XXXX200 0887AFB81039820 Preemptive00000000:00000000 00c462f8 -00001 Ukn (Threadpool Worker)113547c 0887A2E02b220 Preemptive03C50008:03C51FE8 00c462f8 -00001 MTA
2. 为什么会有很多短命线程从 windbg
的输出看有很多的 XXX,那原因是什么呢? 还得先观察下代码,可以看到代码会给 ThreadPool 分发 100 次任务,每个任务也就 1s 的运行时间,这样的代码会造成 ThreadPool 的工作线程处理不及继而会产生更多的工作线程,在某一时刻那些 Sleep 后的线程又会规模性唤醒,ThreadPool 为了能够平衡工作者线程,就会灭掉很多的线程,造成 ThreadPool 中的暴涨暴跌现象 。
经验总结扩展阅读
- 第五周 python实验报告
- 全款买车流程
- 如何挑选折叠衣柜折叠衣柜哪个好
- 止血带止血注意事项
- 第一届冬季残奥会是在哪年举办的
- 第5人格怎么打开塔罗模式
- 原神清泉镇无相之岩怎么开
- 简单的饺子蘸料
- 亲爱的自己第六集剧情
- 樟脑球对人有哪些危害