外贸企业网站建设一条龙标智客logo设计免费生成
news/
2025/9/27 8:24:45/
文章来源:
外贸企业网站建设一条龙,标智客logo设计免费生成,服务公司取名字大全,网站网络优化服务器一#xff1a;背景 1.讲故事今天给大家带来一个入门级的 CPU 爆高案例#xff0c;前段时间有位朋友找到我#xff0c;说他的程序间歇性的 CPU 爆高#xff0c;不知道是啥情况#xff0c;让我帮忙看下#xff0c;既然找到我#xff0c;那就用 WinDbg 看一下。二#xff…一背景 1.讲故事今天给大家带来一个入门级的 CPU 爆高案例前段时间有位朋友找到我说他的程序间歇性的 CPU 爆高不知道是啥情况让我帮忙看下既然找到我那就用 WinDbg 看一下。二WinDbg 分析 1. CPU 真的爆高吗其实我一直都在强调要相信数据口说无凭一定要亲自验证一下可以使用 !tp 命令。0:000 !tp
CPU utilization: 81%
Worker Thread: Total: 32 Running: 0 Idle: 18 MaxLimit: 2047 MinLimit: 2
Work Request in Queue: 0
--------------------------------------
Number of Timers: 1
--------------------------------------
Completion Port Thread:Total: 0 Free: 0 MaxFree: 4 CurrentLimit: 0 MaxLimit: 1000 MinLimit: 2从卦中可以看到当前的 CPU81%果然爆高无疑接下来就得调查下为什么会爆高可以从触发 GC 入手。2. GC 触发了吗要观察是否 GC 触发可以观察下线程列表上是否有 (GC) 字样比如下面的输出。0:006 !t
ThreadCount: 38
UnstartedThread: 0
BackgroundThread: 37
PendingThread: 0
DeadThread: 0
Hosted Runtime: noLock ID OSID ThreadOBJ State GC Mode GC Alloc Context Domain Count Apt Exception0 1 5f0 01310688 2a020 Preemptive 00000000:00000000 0130aa50 0 MTA 2 2 818 0131e358 2b220 Preemptive 00000000:00000000 0130aa50 0 MTA (Finalizer) 3 6 7b0 01374908 202b220 Preemptive 00000000:00000000 0130aa50 0 MTA 4 7 f98 01381c50 102a220 Preemptive 00000000:00000000 0130aa50 0 MTA (Threadpool Worker) 6 3 610 013eba78 2b220 Cooperative 00000000:00000000 0130aa50 1 MTA (GC) 9 44 e04 05585068 1029220 Preemptive 00000000:00000000 0130aa50 0 MTA (Threadpool Worker) 10 25 448 063dab30 21220 Preemptive 00000000:00000000 0130aa50 0 Ukn ...从卦中可以看到6号线程果然带了 (GC) 字样接下来用 kb 观察下到底是哪一代GC。0:006 kb# ChildEBP RetAddr Args to Child
00 05beef18 72bb4825 0b771000 00000003 00000001 clr!WKS::gc_heap::relocate_survivor_helper0x87
01 05beef48 72bb46da 0b771000 00000001 00000000 clr!WKS::gc_heap::relocate_survivors0x93
02 05beef98 72bb1913 00000000 00000001 73180140 clr!WKS::gc_heap::relocate_phase0x8b
03 05bef140 72bb0f69 00000000 00000001 00000001 clr!WKS::gc_heap::plan_phase0x13b8
04 05bef168 72bb12ef 5e7aa9c3 7317fcd0 00000000 clr!WKS::gc_heap::gc10xe8
05 05bef1a0 72bb140c 00000040 7317ff04 7317ff04 clr!WKS::gc_heap::garbage_collect0x447
06 05bef1c8 72bb161c 00000000 00000000 00000040 clr!WKS::GCHeap::GarbageCollectGeneration0x1fb
07 05bef1ec 72bb1696 7317ff04 71a9d900 00000002 clr!WKS::gc_heap::trigger_gc_for_alloc0x1e
08 05bef21c 72bff51a 00000000 00000040 0c1c7aa4 clr!WKS::gc_heap::try_allocate_more_space0x162
09 05bef230 72bff687 00000000 01304d38 72bff140 clr!WKS::gc_heap::allocate_more_space0x18
0a 05bef24c 72ab4477 013ebab8 00000040 00000002 clr!WKS::GCHeap::Alloc0x5c
0b 05bef26c 72ab44f5 01000000 71ab5e90 05bef3f8 clr!Alloc0x87
0c 05bef2b4 72ab4595 5e7aab5f 00000bb8 05bef3f8 clr!AllocateObject0x99
0d 05bef33c 719b8281 71a2417c 05bef358 05bef35c clr!JIT_New0x6b
0e 05bef360 7225652d 00000000 00000000 00000000 mscorlib_ni!System.Threading.Tasks.Task.Delay0x41 [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs 5885]
0f 05bef454 05a9d18a 00000000 00000000 00000000 mscorlib_ni!System.Threading.Tasks.Task.Delay0xd [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs 5843]
...因为 C 默认是 this 协定从 clr!WKS::gc_heap::plan_phase0x13b8 方法的第二个参数 00000001 可知当前触发了 1 代 GC其实 1 代 GC 本来就触发频繁所以问题不大主要就是看是否为 2 代GC即 FullGC。到这里GC触发的路堵死了我们就看下是不是还有其他的可疑情况比如高时钟个数的线程。3. 有长时间运行线程吗如果是当事人可以用 Process Explorer 工具直接观察 Thread 列表的 Cycles Delta 列就能知道比如下面的百度云管家可以看到 11156 号线程占用了太多的时钟周期个数可惜我不是当事人所以只能用 cpuid 命令观察。0:006 !runawayUser Mode TimeThread Time6:610 0 days 0:47:07.98410:448 0 days 0:11:32.53112:17d4 0 days 0:01:34.2659:e04 0 days 0:01:29.46811:16ec 0 days 0:01:11.56213:1458 0 days 0:01:07.703...从卦中可以看到6号线程耗费的时钟个数遥遥领先甩了第二名 10 号线程几条街这个线程非常可疑得好好研究下它的托管栈了。0:006 !clrstack
OS Thread Id: 0x610 (6)
Child SP IP Call Site
05bef2d0 72bb47ae [HelperMethodFrame: 05bef2d0]
05bef344 719b8281 System.Threading.Tasks.Task.Delay(Int32, System.Threading.CancellationToken) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs 5885]
05bef36c 7225652d System.Threading.Tasks.Task.Delay(Int32) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs 5843]
05bef370 05a9d18a xxx.Api.Core.xxxc__DisplayClass2_0..cctorb__0()
05bef45c 719b7118 System.Threading.Tasks.Task.InnerInvoke() [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs 2884]
05bef468 719b6cc0 System.Threading.Tasks.Task.Execute() [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs 2498]
05bef48c 719b70ea System.Threading.Tasks.Task.ExecutionContextCallback(System.Object) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs 2861]
05bef490 719d40c5 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs 954]
05bef4fc 719d3fd6 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs 902]
05bef510 719b6f68 System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs 2827]
05bef574 719b6e72 System.Threading.Tasks.Task.ExecuteEntry(Boolean) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\Task.cs 2756]
05bef584 71a2acbc System.Threading.Tasks.ThreadPoolTaskScheduler.LongRunningThreadWork(System.Object) [f:\dd\ndp\clr\src\BCL\system\threading\Tasks\ThreadPoolTaskScheduler.cs 49]
05bef588 719a70e3 System.Threading.ThreadHelper.ThreadStart_Context(System.Object) [f:\dd\ndp\clr\src\BCL\system\threading\thread.cs 74]
05bef594 719d40c5 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs 954]
05bef600 719d3fd6 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs 902]
05bef614 719d3f91 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) [f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs 891]
05bef62c 71a28cae System.Threading.ThreadHelper.ThreadStart(System.Object) [f:\dd\ndp\clr\src\BCL\system\threading\thread.cs 93]
05bef770 72a90096 [GCFrame: 05bef770]
05bef954 72a90096 [DebuggerU2MCatchHandlerFrame: 05bef954]从线程栈上看还好有一个托管方法 xxx.Api.Core.xxxc__DisplayClass2_0..cctorb__0 接下来观察下源码修剪后的代码如下static xxxUploadPool()
{_queue new ConcurrentQueuexxxModel();_xxx new xxxService();int second Configuration.xxx * 1000;Task.Factory.StartNew(delegate{while (true){lock (_queue){if (_queue.Count 0 _queue.TryDequeue(out var result)){_xxx.UploadFilexxxx(result._path, result._repositoryName, xxx);}}Task.Delay(second);}}, TaskCreationOptions.LongRunning);
}这段代码很有意思它的本来想法就是开启一个长线程然后在长线程中不断的轮询等待问题就出在了这个等待上 即 Task.Delay(second); 这句 这句代码起不到任何作用而且一旦 _queue 中的数据为空就成了死循环 给 CPU 打满埋下了祸根。这里有一个疑问一个线程能把 CPU 打满那太瞧不起CPU 了肯定是有对等的 core 个数的线程一起发力打爆CPU那如何验证观察下 CPU 的个数。0:006 !cpuid
CP F/M/S Manufacturer MHz0 6,85,4 GenuineIntel 31931 6,85,4 GenuineIntel 3193也就说只要有两个线程进入了 xxxUploadPool 那就够了现象也正是如此。三总结 这段代码确实很有意思猜测原来就是 Thread.Sleep(second) 但为了赶潮流改成了 Task.Delay(second)在不清楚后者的使用场景下给 CPU 间歇性爆高埋下了祸根所以大家在使用新的语法时一定要弄清楚场景万不可生搬硬套。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/916737.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!