在.NET中进行事后分析有什么可能性(例如在程序崩溃之后)?

时间:2009-01-18 13:27:49

标签: c# .net maintenance

假设有一个C#程序,它用作Windows服务。让我们假设服务已经疯狂,并且像疯了一样消耗CPU和内存。它需要很快重新启动,因为它是一个生产系统。所以我没有太多时间收集运行时信息。也许快速浏览任务管理器......就是这样。

之后,我所拥有的只是log4net日志文件和用于事后分析的Windows事件日志。

假设我找到了问题的原因。其他人修复了它,也许程序员添加了一些额外的日志记录,所以我下次可以更快地找到类似的问题。尽管如此:我仍然依赖于日志文件的质量,并希望下次问题能够在记录中以某种方式显示出来。

还有其他方法进行验尸分析吗?也许像线程转储(如java),内存转储或其他东西,这可能有助于事后分析?也许一些内置的.NET框架工具可以提供帮助吗?

我对真实的项目体验以及如何解决这个维护问题非常感兴趣,我认为这对大多数程序员来说都是非常真实的。

5 个答案:

答案 0 :(得分:2)

您可以使用.NET执行故障转储,并使用windbg / sos(和sosassist)查看它们。不简单,但它的工作原理。但相当硬核。搜索“+ windbg + .NET”应该很有趣。

除此之外 - 资源柜台?日志文件?您可以很容易地看到很多可以看到的东西。

答案 1 :(得分:2)

正如Marc所说,WinDbg + SoS会让你调试很多问题,你无法在Visual Studio中真正解决。有一些很棒的教程this blog

对于内存问题,您还可以查看Perfmon中的.NET性能计数器。您可以查看对象所在的位置(哪一代)以及在垃圾收集中花费的时间。这应该会给你一些有用的信息。如果你想知道为什么没有收集对象,WinDbg和SoS就是你要走的路。为了引导您完成简单的会话,步骤如下:

  1. 使用!dumpheap -stat检查堆,查找大量实例。您可能已经知道在任何给定时刻您希望在堆上找到什么,所以如果有任何不寻常的东西,请查看。

  2. 选择随机实例并对实例的地址执行!gcroot。这将告诉你为什么没有收集对象。

  3. 重复

  4. 可能比活着更长时间保持活动的候选人:事件,静态和终结队列等等。

    您可能还想查看我对this question的回答,以查看更多WinDbg内容。

答案 2 :(得分:1)

使用WinDbg和SOS进行事后分析的一个很好的资源是Tess Ferrandez'series of blog entries关于这个问题。

编辑:链接已更新

答案 3 :(得分:1)

不幸的是,我必须做相当多的事情 - 我遇到的最好的工具是sbk附带的cordbg(你的.net版本需要正确的版本)。 http://msdn.microsoft.com/en-us/library/a6zb7c8d.aspx了解详情。

附加到cordbg(a< [pid]>)中的运行进程,附加到每个正在运行的线程(t< [tid]>),然后为每个线程(w)转储堆栈。

使用一个小的vb脚本自动执行此任务,然后转储到文件将允许您多次运行此工具,将输出捕获到文件。比较所有线程堆栈将使您非常了解应用程序在何时花费时间。

这种方法的好处,特别是在自动化转储时,您可以非常快速地获取所有信息,并在最短的时间内重新启动您的流程。

答案 4 :(得分:0)

如果进程仍处于活动状态,那么您可以对其运行Managed Stack Explorer以快速了解它正在执行的操作。您可以在没有明确安装的情况下运行它。

除此之外,完整的转储+ windbg + SOS为您提供了最多的信息,但是获取它并非易事。