.NET 中的事后分析都有哪些可能性(例如,在程序崩溃后)?
Posted
技术标签:
【中文标题】.NET 中的事后分析都有哪些可能性(例如,在程序崩溃后)?【英文标题】:What possibilities are there for post mortem analysis in .NET (e.g. after a crash of a program)?.NET 中的事后分析有哪些可能性(例如,在程序崩溃后)? 【发布时间】:2009-01-18 13:27:49 【问题描述】:假设有一个 C# 程序,它被用作 Windows 服务。让我们假设服务变得疯狂并且疯狂地消耗 CPU 和内存。它需要尽快重新启动,因为它是一个生产系统。所以我没有太多时间来收集运行时信息。也许快速浏览一下任务管理器......就是这样。
在那之后,我只有 log4net 日志文件和用于事后分析的 windows 事件日志。
假设我找到了问题的原因。其他人修复了它,也许程序员添加了一些额外的日志记录,这样我下次可以更快地找到类似的问题。尽管如此:我仍然依赖于日志文件的质量,并希望下次出现问题时会以某种方式暴露在日志中。
还有其他方法可以进行事后分析吗?也许像线程转储(如在 java 中)、内存转储或其他可能有助于事后分析的东西?也许一些内置的 .NET 框架工具可以提供帮助?
我对真实的项目经验以及您将如何尝试解决这个维护问题非常感兴趣,我认为这对大多数程序员来说都是非常真实的。
【问题讨论】:
【参考方案1】:正如 Marc 所说,WinDbg + SoS 可以让您调试很多问题,但您无法在 Visual Studio 中真正解决。有一些很棒的教程this blog。
对于内存问题,您还可以查看 Perfmon 中的 .NET 性能计数器。您可以查看对象的位置(哪一代)以及垃圾收集花费了多少时间。这应该会给你一些有用的信息。如果您想知道为什么没有收集对象,WinDbg 和 SoS 是您的最佳选择。为了引导您完成一个简单的会话,步骤如下:
使用!dumpheap -stat
检查堆,查找大量实例。您可能对在任何给定时刻希望在堆上找到什么有所了解,因此,如果有什么不寻常的地方,请调查一下。
选择随机实例并在实例地址上执行!gcroot
。这将告诉您为什么没有收集对象。
重复
使内容保持比应有的时间更长的可能候选对象是:事件、静态和终结器队列等等。
您可能还想查看我对this question 的回答,以了解更多 WinDbg 内容。
【讨论】:
【参考方案2】:您可以使用 .NET 进行故障转储,并使用 windbg / sos(和 sosassist)查看它们。不简单,但它有效。但相当硬核。搜索“+windbg +.NET”应该会很有趣。
除此之外 - 资源计数器?日志文件?您可能看到的很多东西都可以很容易地启用。
【讨论】:
【参考方案3】:不幸的是,我不得不做很多这样的事情——我遇到的最好的工具是 sdk 附带的 cordbg(你需要为你的 .net 版本提供正确的版本)。 http://msdn.microsoft.com/en-us/library/a6zb7c8d.aspx了解详情。
附加到cordbg(a )中正在运行的进程,附加到每个正在运行的线程(t ),然后转储每个线程的堆栈(w)。
使用一个小的 vb 脚本自动执行此任务,然后转储到文件中,您可以多次运行此工具,将输出捕获到文件中。比较所有线程堆栈可以让您很好地了解应用程序将时间花在哪里。
这种方法的好处是,尤其是在自动转储方面,您可以非常快速地获取所有信息并在最短的时间内重新启动您的流程。
【讨论】:
【参考方案4】:使用 WinDbg 和 SOS 进行事后分析的一个很好的资源是 Tess Ferrandez'series of blog entries 关于这个主题。
编辑:链接已更新
【讨论】:
我认为正确的链接是:blogs.msdn.com/tess/pages/…?【参考方案5】:如果该进程仍然存在,那么您可以对它运行Managed Stack Explorer 以快速了解它正在做什么。您可以在没有显式安装的情况下运行它。
除此之外,完整转储 + windbg + SOS 可以为您提供最多的信息,但获得它并非易事。
【讨论】:
以上是关于.NET 中的事后分析都有哪些可能性(例如,在程序崩溃后)?的主要内容,如果未能解决你的问题,请参考以下文章