w3wp占用CPU过高
w3wp占用CPU过高
在此之前项目有发生过两次类似的状况,都得以解决,但最近又会发现偶尔CPU会跑满,虽然之前使用过WinDbg解决过两次问题但人的记忆是不可靠的,今天处理同样问题的时候还是遇到了一些障碍,这一次希望可以记录的更全面些。
上两次的博文链接:记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)、EntityFramework中的线程安全,又是Dictionary。
首先请大家不要喷我,因为这一次还是关于Dictionary的一些低级错误,我自己看到都无语了。。。
抓取Dump
使用任务管理器抓取Dump,如果操作系统较低可以使用“Process Explorer”。

使用WinDbg分析
1.使用WinDbg打开dump文件。
2.加载sos.dll
命令:.loadby sos clr

3.查看相关线程信息
命令:!threads –special
special参数会将由CLR创建的特殊线程单独列出便于减少线程的排查工作。

红框圈出的是我们要重点排查的线程(工作者线程),至于其它的则是一些CLR自拥有的一些线程,如:GC线程、对象释放线程、计时器线程、I/O线程等。
线程类型的名称翻译:
- GC:垃圾回收线程
- Finalizer:对象释放线程,.Net至少有一个,用于专门处理对象释放。
- Timer:计时器线程
- ThreadpoolWorker:工作者线程
- IOCompletion:I/O线程
4.查看具体线程堆栈
命令:~{ThreadId}s、!clrstack
~{ThreadId}s:将当前上下文切换到指定的线程内

!clrstack:得到当前的线程的堆栈信息

第二个红框的前两句太长了,我复制在下面:
000000d784afe180 000007fda1efa328 System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.Collections.Generic.KeyValuePair`2[[System.__Canon, mscorlib],[System.Boolean, mscorlib]], mscorlib]].FindEntry(System.__Canon)
000000d784afe1f0 000007fda1ef96eb System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.Collections.Generic.KeyValuePair`2[[System.__Canon, mscorlib],[System.Boolean, mscorlib]], mscorlib]].TryGetValue(System.__Canon, System.Collections.Generic.KeyValuePair`2<System.__Canon,Boolean> ByRef)
可以发现,是在TryGetValue方法时堵塞了,而看到红框中的最后一句则可以发现是EnumParseCacheHelper的Parse方法出了问题,这个方法主要是对枚举转换的一个缓存处理以提升性能。
为了再次确认问题,我继续对19、20、21、24等线程进行了查看,都是在这里堵塞了,那么问题浮出水面了,下面就去看代码,并且解决它。
解决问题
找到对应的代码:

问题显而易见,CacheDictionary是一个全局静态的字段,而我在下面方法使用它的时候丝毫没有注意并发下的情况,没有加锁来保证线程安全。。看到这感觉不可思议怎么犯这么低级的错误。。。
解决它方式:

解决方式很简单,使用了.NET4提供的线程安全的字典:ConcurrentDictionary。
关于这一次问题的思考
Dictionary为什么这么容易堵塞
这边引用之前的博文内容:
我知道Dictionary不是一个线程安全的类型,但我原本以为Dictionary在非线程安全方式下访问时数据会错乱,而不会堵塞或者死锁,而这次的这个问题让我感觉到讶异,为什么Add一个项目会造成堵塞?
反编译Dictionary的源码后发现异常的复杂,也没有细究,所以下面的一段描述大家抱有自己的想法去阅读,可能是错的也可能是对的。
上面是我认为存在问题的地方,当一个线程执行过Initialize后buckets数组的值被修改,而第二个线程同时进入了Initialize方法,那么第一个线程所维护的值被破坏,造成在算法环节出现了死循环,这也可以说明了为什么cpu有时候是50%有时候是99%的问题。
当前有多少个线程发生了这种状态,如果发生这种状态的线程越多则代表cpu占用越多。
这次问题的经验:以后在使用集合或字典时首先应该先想到System.Collections.Concurrent命名空间,虽然它的性能在正常情况下低于普通的Dictionary,但那么几十或者几百毫秒的损失对于稳定性来说微不足道,也减少了问题的发生。
写在最后
因为Rabbit.WeiXin是一个开源项目当然第一件事情就是发布更新。。避免更多的人出现此问题。

交流方式
QQ群:384413261(RabbitHub)
Email:majian159@live.com
w3wp占用CPU过高的更多相关文章
- 再记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)
在此之前项目有发生过两次类似的状况,都得以解决,但最近又会发现偶尔CPU会跑满,虽然之前使用过WinDbg解决过两次问题但人的记忆是不可靠的,今天处理同样问题的时候还是遇到了一些障碍,这一次希望可以记 ...
- 记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)
项目上线以来一直存在一个比较揪心的问题,和一个没有信心处理的BUG,那就是在应用程序启动时有可能会导致cpu跑满99%或持续在一个值如50%左右,这样一来对服务器的压力是非常大的,经常出现服务器无法远 ...
- w3wp.exe占用cpu特别高
w3wp.exe占用cpu特别高,百度了一下在任务管理器标记出PID可以看到进程号. 试了一下,发现一个xxx网站占用cpu特别高,然后就结束了下进程,再重启网站cpu一下子降下来. 很奇怪,还需要具 ...
- memcache占用CPU过高的解决办法
Simon最近为公司服务器操碎了心 , 先是mysqld进程占用CPU过高 , 导致服务器性能变低 ,网站打开太慢.通过增加max_connections及table_cache解决了问题 ,随后发现 ...
- JVM进程占用CPU过高问题排查
上午收到报警,某台机器上的CPU负载过高,通过逐步的排查,解决了问题,下面记录一下整个排查的过程. 首先,登录上对应的机器,通过top命令找到占用CPU过高的进程ID,也就是PID,为29126, 然 ...
- 关于linux系统CPU篇--->不容易发现的占用CPU较高进程
1.系统的CPU使用率,不仅包括进程用户态和内核态的运行,还包括中断处理,等待IO以及内核线程等等.所以,当你发现系统的CPU使用率很高的时候,不一定能找到相对应的高CPU使用率的进程 2.案例分析, ...
- 查找linux下进程占用CPU过高的原因,以php-fpm为例
很多时候,线上服务器的进程在某时间段内长时间占用CPU过高,为了优化,我们需要找出原因. 1.找出占用CPU最高的10个进程 ps aux | sort -k3nr | head -n 10 或查看占 ...
- Mysql占用CPU过高如何优化?(转)
原文:http://bbs.landingbj.com/t-0-241441-1.html MySQL处在高负载环境下,磁盘IO读写过多,肯定会占用很多资源,必然CP会U占用过高. 占用CPU过高,可 ...
- Mysql占用CPU过高如何优化,如何解决
2017-02-28 15:13 331人阅读 评论(0) 收藏 举报 MySQL占用CPU过高如何优化 一次生产DB服务器的 超负荷运行问题解决: 1.查看生产DB服务器top列表, 执行 to ...
随机推荐
- CentOS 7 安装MySql Server 5.6
1. 安装MySql Server 在/etc/yum.repos.d/目录下添加以下文件mysql-community.repo文件,内容如下: [mysql56-community] name=M ...
- 使用OGG"Loading data from file to Replicat"的方法应该注意的问题:replicat进程是前台进程
使用OGG的 "Loading data from file to Replicat"的方法应该注意的问题:replicat进程是前台进程 因此.最好是在vncserver中调用该 ...
- LeetCode: Unique Binary Search Trees [095]
[题目] Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For ...
- 一个使用Java jdk8中Nashorn(Java javascript引擎)设计的Web开发框架
地址:https://github.com/iboxdb/hijk 採用给框架开发应用,简单直接.开发效率高 下载后 set PATH to /JAVA 8_HOME/bin jjs build.js ...
- 《深入理解mybatis原理》 Mybatis初始化机制具体解释
对于不论什么框架而言.在使用前都要进行一系列的初始化,MyBatis也不例外. 本章将通过下面几点具体介绍MyBatis的初始化过程. 1.MyBatis的初始化做了什么 2. MyBatis基于XM ...
- Xamarin For Visual Studio 3.7.165 完整离线破解版
原文 Xamarin For Visual Studio 3.7.165 完整离线破解版 Xamarin For Visual Studio就是原本的Xamarin For Android 以及 Xa ...
- 两种Data Table参数化设置的区别
首先介绍Data Table的语法: 1.DataTable.value(ParameterID, SheetID) 2.DataTable(ParameterID, SheetID) 以上2种方法的 ...
- 在Amazon AWS RHEL 7上安装 配置PPTP VPN
0 前言 0.1 为什么需要VPN? 国内的VPN不是必须,但是国外的VPN是很有用的.连接到国外的VPN服务器之后就可以访问Google,Facebook, Youtube等网站,没有Google的 ...
- 辛星解读为什么PHP须要模板
近期有个人问我:为什么PHP须要模板呢?整个站点的编写都是我一个人完毕的,从前端到后端,都是这样,我一个人写站点是不是就不须要模板了呢?我当时还真给问住了,也没想好非常合适的回答它的方式,于是就随便说 ...
- Android 从硬件到应用程序:一步一步爬上去 5 -- 在Frameworks蒂姆层硬件服务
Android Frameworks层提供硬件服务,Android系统APP能够调用这些硬件服务,而硬件则完全控制.实现应有的功能.上一页下一页.为了这一个frameworks高层的应用java接口硬 ...

