【问题标题】:How can I view the async stack traces while debugging a .NET application in Visual Studio?在 Visual Studio 中调试 .NET 应用程序时如何查看异步堆栈跟踪?
【发布时间】:2022-01-04 13:11:36
【问题描述】:

我试图找出复杂的基于 C# 的应用程序中(可能的)内存泄漏的原因。由于应用程序的 CPU 和内存使用率很高,由于系统变得非常缓慢且不稳定,因此我无法在运行时调试问题,因此我在运行时通过任务管理器创建了应用程序的转储 (dmp) 文件,然后打开该文件转储以在我的本地 Visual Studio 2022 实例中进行进一步分析。当我现在尝试在创建转储时查看应用程序的线程时,它只向我显示调用堆栈,直到执行异步操作为止。在这个异步执行中发生的一切似乎都无法访问。在调用堆栈中,它只是说它正在等待异步进程,我应该双击或按 Enter 以显示异步调用堆栈。但是,这似乎没有任何作用。我是否遗漏了什么,或者我如何才能看到异步进程中发生了什么?

【问题讨论】:

  • 你试过并行堆栈窗口吗? (调试->Windows->并行堆栈)
  • @PMF 是的,但我在那里看不到任何有用的信息。只要我没有遗漏任何东西,基本上应用程序中的每个线程似乎都在休眠或通过 Task.Wait 等待,但应用程序正在消耗千兆字节的内存。您是否知道任何其他方法可以根据我创建的 dmp 文件找出导致这种高内存消耗的原因?我认为任何线程的调用堆栈都不再有助于解决这个问题。
  • 没错,内存使用情况很难找到。但是,如果 CPU 使用率也很高,通常应该会看到线程在做某事。我分析这种情况的方法是使用 dotTrace 或 dotMemory、Resharpers 内存和 CPU 分析工具。他们可以免费试用。
  • 澄清一下:我不隶属于 JetBrains,也不想做广告,但这些工具正是为了这个目的。
  • 不要等那么久,千兆字节是不可能挖掘出来的。使用内存快照功能诊断增长:docs.microsoft.com/en-us/visualstudio/profiling/…

标签: c# visual-studio debugging asynchronous memory-dump


【解决方案1】:

查找内存泄漏的典型方法是创建两个或多个内存快照/转储,并将它们与内存调试器进行比较,以查看是否存在某种类型的对象似乎只会增加计数。在尝试查找内存泄漏时,我不确定堆栈跟踪是否会提供这么多价值。

我主要使用 dotMemory,但没有隶属关系。我希望大多数有能力的工具都具有相同的功能,但术语可能会有所不同。

应该有一个comparison view,您应该可以在其中按 delta countdelta bytes 对对象进行排序。这通常可以很好地指示哪些对象正在泄漏。

一旦您有了候选类型,您应该能够检查该类型的实例,并通过某种方式查看retention graph,您可以在其中查看使您的实例保持活动状态的对象图。如果您发现任何可疑之处,您应该查看代码并查看是否存在泄漏的可能性。

常见的原因是未注册的事件处理程序。如果一个对象注册了一个事件处理程序,它还应该确保它是未注册的。如果在构造函数中完成,则应在 dispose 方法中实现 IDisposable 并取消注册,并确保始终释放对象。可能使用仅针对未处置的对象运行的终结器,它会记录或以其他方式提醒您该对象未处置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多