遇到一个用.net3.5(基于.net2.0)版本开发的应用网站,网站启动后不久,CPU就陷入持续99%-100%的问题。而且一旦开始就停不了,一直这样。
使用任务管理器生成了内存快照的转储文件w3wp.dmp,但使用Visual Studio打开这个转储文件,发现不能进行托管代码(C#代码)进行调试,也就无法看到C#代码的调用堆栈,无法分析原因。
最后通过WinDbg成功解决了问题。具体步骤如下:
1、安装WinDbg。如下:
2、启动要安装与待调试程序一致的x64或x32版本。
3、File > Open Crash Dump,打开w3wp.dmp文件。
4、在底部运行命令:.load C:\Windows\Microsoft.NET\Framework64\v2.0.50727\SOS.dll
启用托管代码调试。
5、运行命令:.loadby sos mscorwks
加载.net3.5的运行模块mscorwks。
6、运行命令:~*e!dumpstack
查看所有线程栈。
此时就可以看到所以线程当前的运行堆栈了。
然后我发现好几个线程都停在这:
根据堆栈分析代码后,发现是因为没有加锁,导致多个线程同时操作了同一个Dictionary对象。.net的Dictionary对象是线程不安全的,很容易导致并发问题,导致在内部死循环,从而Cpu飙满。
另外补充下,如果是内存占用过大,可以这样分析:
前面5步一样。然后执行!dumpheap -stat
可以列举所有的对象及数目:
然后执行!dumpheap -min 8196 -mt 000007fe8ca30da8
可以查看大小最少为8196的所有String对象,这里的000007fe8ca30da8
对应上图中的倒数第2行内存地址。
然后执行!do 00000001bfa6c530
(同样00000001bfa6c530也是上图中的地址)即可查看这个对象的信息:
通过分析大对象和数目过多的对象,可分析内存被占用的情况。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。