记一次.NET某旅行社Web站CPU爆高详解

可惜发过来的 dump 只有区区2G,能在这里面找到内存溢出那真有两把刷子。。。??????,所以我还是希望他的程序内存涨到 5G+ 的时候再给我看看,既然内存看不了,那就看看这个偶尔飙升的CPU是个啥情况?老办法,上windbg说话。

windbg 分析

 CPU 到底是多少

要想查看这个快照生成时机器的cpu使用率,可以使用 !tp 命令。


  1. 0:033> !tp 
  2. CPU utilization: 93% 
  3. Worker Thread: Total: 800 Running: 800 Idle: 0 MaxLimit: 800 MinLimit: 320 
  4. Work Request in Queue: 3203 
  5.     Unknown Function: 000007fefb551500  Context: 000000002a198480 
  6.     Unknown Function: 000007fefb551500  Context: 0000000028a70780 
  7.     Unknown Function: 000007fefb551500  Context: 000000002a182610 
  8.     Unknown Function: 000007fefb551500  Context: 00000000262a2700 

本以为一个简单的命令,结果屏幕上呼啦啦的一堆。。。有点意外,从上面的卦象看:当前CPU利用率是 93%,没毛病,确实是CPU飙升,比较惊讶的是,线程池上限800个线程全部被打满,太悲壮了。。。可更悲壮的是线程池队列中还有 3203 个待处理的任务,可以猜测程序不仅高CPU,还有挂死现象。。。

接下来的问题是:这800个壮士到底怎么啦,程序现在正是用人之际,要想找出答案,还是按照我的惯性思维,查看同步块表。

线程同步块表

要想查看同步块表,可以使用 !synblk 命令。


  1. 0:033> !syncblk 
  2. Index SyncBlock MonitorHeld Recursion Owning Thread Info  SyncBlock Owner 
  3.   188 0000000010defc28            1         1 000000001e8fb400 9f4 715   00000003ff1e3d80 System.Web.HttpApplicationStateLock 
  4. 126159 000000001e424e28            1         1 0000000023425e00 1f14 695   0000000301210038 ASP.global_asax 
  5. 126173 00000000281acaf8            1         1 0000000024b8ea70 24ec 785   00000000ff8c5e10 ASP.global_asax 
  6. 126289 00000000247a4068            1         1 0000000027ee93c0 808 413   0000000306aca288 ASP.global_asax 
  7. 126368 0000000027180dd8            1         1 0000000028005cb0 1e7c 650   00000002008d6280 ASP.global_asax 
  8. 126489 0000000027211dd8            1         1 0000000026862420 ec4 220   000000030611a290 ASP.global_asax 
  9. 126788 00000000247924b8            1         1 0000000021871ff0 2784 529   00000004039901a8 ASP.global_asax 
  10. 126843 00000000285b8d28            1         1 000000001cbd6710 2170 456   00000004007ec748 ASP.global_asax 
  11. 126934 0000000021b212b8            1         1 0000000026ca7590 16cc 472   000000030090e810 ASP.global_asax 
  12. 127251 0000000024769188            1         1 000000002831eaf0 2b68 648   0000000207051038 ASP.global_asax 
  13. … 
  14.  
  15. —————————– 
  16. Total           141781 
  17. CCW             2 
  18. RCW             4 
  19. ComClassFactory 0 
  20. Free            140270 

我去,又是呼啦啦的一堆,从上面的卦象可以看出两点信息:

  • MonitorHeld: 1

表示当前有一个线程正在持有锁。

  • ASP.global_asax , System.Web.HttpApplicationStateLock

表示当前线程持有的对象。

不过综合来看有点奇怪,除了第一个线程持有 HttpApplicationStateLock,后面所有的线程持有的 ASP.global_asax 对象都有不同的内存地址:0000000301210038,00000000ff8c5e10,感觉lock的对象不是线程共享式的 static,更像是一个 instance,蛮有意思的,接下来抽两个线程看看它的线程栈,比如这里的:715,695。

 查看线程栈

要想查看线程栈,可以用 !clrstack 命令。

【声明】:芜湖站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

相关文章