有谁知道有一个工具可以帮助我弄清楚why我们在托管应用程序中看到 CPU 失控?
我是什么not寻找:
流程浏览器 http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx,它有一个很棒的功能,可以让您查看每个线程的 CPU,但您无法获得托管堆栈跟踪。此外,它需要相当熟练的用户。
风数据库+SOS http://msdn.microsoft.com/en-us/library/bb190764.aspx,它可能可以用来通过抓取一堆转储来弄清楚发生了什么。但自动化并非易事,而且有点繁重。
成熟的分析器(如 dottrace 或 redgate),许可很复杂,而且该工具是一种过度杀伤力,需要相当繁重的安装。
我在寻找什么:
- 我可以将一个简单的 exe(没有安装程序)发送给客户。他们运行 10 分钟后,会生成一个文件并发送给我。该文件包含消耗最多 CPU 的线程的详细信息及其在此期间的堆栈跟踪。
从技术上讲,我知道可以创建这样的工具(使用 ICorDebug),但如果这样的工具已经存在,我不想投入任何时间。
那么,有人知道这样的事情吗?
基本解决方案
- Grab managed每个托管线程的堆栈跟踪。
- Grab 基本线程统计 http://msdn.microsoft.com/en-us/library/ms683237(VS.85).aspx对于每个托管线程(用户模式和内核时间)
- 稍等一会
- 重复(1-3)
- 分析结果并找到消耗最大 CPU 使用量的线程,向用户呈现这些线程的堆栈跟踪。
管理与管理非托管堆栈跟踪
托管和非托管堆栈跟踪之间存在很大差异。托管堆栈跟踪包含有关实际 .Net 调用的信息,而非托管堆栈跟踪包含非托管函数指针列表。由于 .Net 是抖动的,因此在诊断托管应用程序的问题时,非托管函数指针的寻址几乎没有什么用处。
如何获取任意 .Net 进程的非托管堆栈跟踪?
有two ways http://blogs.msdn.com/jmstall/archive/2004/10/22/246151.aspx您可以获得托管应用程序的托管堆栈跟踪。
- 使用 CLR 分析(又名 ICorProfiler API)
- 使用 CLR 调试(又名 ICorDebug API)
生产上用什么比较好?
与分析 API 相比,CLR 调试 API 具有非常重要的优势,它们允许您附加到运行过程。在诊断生产中的性能问题时,这一点至关重要。在应用程序使用几天后,由于代码执行的某些意外分支,经常会出现 CPU 失控的情况。此时重新启动应用程序(为了分析它)不是一个选项。
cpu分析器.exe
因此,我编写了一个无需安装程序的小工具,并使用 ICorDebug 执行上述基本解决方案。它基于MDBG源代码 http://blogs.msdn.com/jmstall/archive/2005/11/08/mdbg_linkfest.aspx全部合并到一个 exe 中。
它以可配置的时间间隔(默认为 1000 毫秒)对所有托管线程进行可配置(默认为 10)数量的堆栈跟踪。
这是一个示例输出:
C:\>cpu-analyzer.exe evilapp
------------------------------------
4948
Kernel Time: 0 User Time: 89856576
EvilApp.Program.MisterEvil
EvilApp.Program.b__0
System.Threading.ExecutionContext.Run
System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal
System.Threading._ThreadPoolWaitCallback.PerformWaitCallback
... more data omitted ...
请随意尝试一下该工具。可以下载来自我的博客 http://samsaffron.com/archive/2009/11/11/Diagnosing+runaway+CPU+in+a+Net+production+application.
EDIT
展示我如何使用 cpu-analyzer 来诊断生产应用程序中的此类问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)