2016年09月28日

.Net网站程序疑难杂症Dump内存分析

作者 非鱼
有些时候.Net的站点在测试时没问题,上到正式环境出现CPU 突然占用100%的问题,或者突然进程崩溃的问题,当代码量比较大的时候,基本上完全无法下手找到问题,在系统的日志里你也找不到任何有用的信息。这时候几乎只能依赖于Dump内存进行分析,查看当时情况下的进程中正在执行的过程,来查找可能出现问题的原因。
对CPU占用100%的问题处理:
ProcDump 8.0下载,只有一个400K主程序,不需要其它附加内容。
当指定进程的CPU占用超过30%连续3秒的时候抓取完整dump,抓取2次后退出。
另外在进程执行过程中抓取之前,程序中触发的异常信息也会直接显示在命令行窗口中。

procdump -ma -c 30 -s 3 -n 2 -e 1 -f “” 5960(Process Name or PID) -o E:\Procdump\Log

    -ma 生成full dump, 即包括进程的所有内存. 默认的dump格式包括线程和句柄信息.
    -c 在CPU使用率到达这个阀值的时候, 生成dump文件.
    -s CPU阀值必须持续多少秒才抓取dump文件.
    -n 在该工具退出之前要抓取多少个dump文件.
-o dump文件保存目录.
其它可用参数:
-t
Write a dump when the process terminates.
-m
Memory commit threshold in MB at which to create a dump.
-e Write a dump when the process encounters an unhandled exception. Include the 1 to create dump on first chance exceptions.
分析Dump还是需要用windbg(安装WindowsDevelopKit):
打开windbg,将对应的Dump文件拖进来,先加载.Net符号文件:
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll
然后:
!threadpool,查看线程池的CPU使用量
!runaway,查看线程占用CPU时间
~28s,切换到28这个线程(占用CPU前几名的程序,可能都需要切换过去看一下)
!clrstack,到具体某个线程后,查看当前线程中正在执行的托管代码,到这一步基本就可以看出问题
其它命令:
!analyze -v 自动分析异常信息
输出信息中的关键信息:
然后进入43这个进程,查看托管代码:
基本可以锁定是由于Senparc这个库里面的LocalCacheLock中的RetryLock方法导致的死锁。
另外!dumpstack -ee也可以用来查找异常信息
对进程自动崩溃的问题处理(系统事件查看器中显示StackoverflowException,此异常用try catch无法捕获):
除上面的procdump -t方法之外,还可以用windbg中包含的adplus工具来生成dump:
adplus -Crash -pn w3wp.exe -FullOnFirst -o d:\output
对生成的Dump文件的分析方式同上。