记一次 .NET 某娱乐聊天流平台 CPU 爆高分析

一:背景1.讲故事前段时间有位朋友加微信,说他的程序直接 CPU=100%,每次只能手工介入重启,让我帮忙看下到底怎么回事,哈哈,这种CPU打满的事故,程序员压力会非常大, 我让朋友在 CPU 高的时候抓 2 个 dump 下来,然后发给我分析 。
二:WinDbg 分析1. CPU 真的被打满了吗?为了防止南辕北辙,一定要用 !tp 命令去验证下是不是真的 CPU 爆高 。
0:000> !tpCPU utilization: 100%Worker Thread: Total: 21 Running: 7 Idle: 0 MaxLimit: 32767 MinLimit: 4Work Request in Queue: 3    AsyncTimerCallbackCompletion TimerInfo@00000000042d2430    AsyncTimerCallbackCompletion TimerInfo@00000000042d2f90    AsyncTimerCallbackCompletion TimerInfo@000000000420c150--------------------------------------Number of Timers: 0--------------------------------------Completion Port Thread:Total: 18 Free: 9 MaxFree: 8 CurrentLimit: 18 MaxLimit: 1000 MinLimit: 4【记一次 .NET 某娱乐聊天流平台 CPU 爆高分析】从卦中看确实 100%,太牛了,而且 WorkRequest 还有任务堆积现象,确认无疑后,接下来看下是谁引发的?
2. 谁导致的 CPU 爆高根据惯例首先怀疑是不是 GC 触发所致,可以用 !t 查看下线程列表,观察下有没有 GC 字样 。
:000> !tThreadCount:      53UnstartedThread:  0BackgroundThread: 53PendingThread:    0DeadThread:       0Hosted Runtime:   no                                                                                                        Lock       ID OSID ThreadOBJ           State GC Mode     GC Alloc Context                  Domain           Count Apt Exception   4    1 1240 00000000021cdf30    2a220 Preemptive  0000000000000000:0000000000000000 00000000021d94c0 0     MTA  23    2 4db4 00000000041cdaa0    2b220 Preemptive  0000000000000000:0000000000000000 00000000021d94c0 0     MTA (Finalizer)  ...  65  156 22f4 000000000b1a3f60  8029220 Preemptive  00000004527751F0:0000000452775EE8 00000000021d94c0 0     MTA (Threadpool Completion Port)  66  205 2ef8 000000000b1a1080  8029220 Preemptive  0000000157641DE0:00000001576435B0 00000000021d94c0 0     MTA (Threadpool Completion Port)  ...从卦中看没有 GC 字样,也表明这个程序并不是由 GC 触发所致,接下来该怎么排查呢? 一般来说 CPU 的爆高是由线程抬起来的,所以接下来就是看下 CPU 的档次和各个线程栈,看有没有什么新线索, 可以使用 ~*e !clrstack。

经验总结扩展阅读