c# - 我如何调查终结队列和终结幸存者

标签 c# performance garbage-collection dispose finalizer

我正在调查我们的应用程序中的 GC 和内存使用情况,并注意到我们似乎有成千上万的终结幸存者。不幸的是,仅凭数字并不能真正告诉我我们是否有问题。然而,我们看到了一般的性能问题,而且我们确实有很高的内存使用率并且在 GC 上花费了大量时间。

理想情况下,我们无法控制的任何东西都不应该进入终结队列。如果是这样,那就是一个错误。有什么方法或工具可以用来检查吗?我听到的一个建议是有一个带有终结器的特殊构建,在它们被执行时记录下来,但这是相当多的努力,并且只适用于我们拥有其类型的对象。有没有更简单的方法?

是否值得调查终结幸存者?如果是,怎么办?

最佳答案

使用WinDbgPsscor2Psscor4扩展名(取决于您的应用程序使用的版本)。不幸的是,目前还没有 .NET 4.5 的版本。设置调试环境(安装 WinDbg 并将 Psscor 文件复制到其文件夹)后,创建进程转储。例如,您可以在 Procdump 的帮助下轻松完成工具:

procdump -ma <PID>

然后使用 File -> Open Crush Dump 选项加载转储。加载适当版本的 Psscor:

.load psscor4

然后执行命令从 Microsoft 服务器下载符号(如果需要),确保您有互联网连接:

!symfix

从现在开始,您应该可以访问许多非常有趣的命令(查找 !help 以列出它们)。查看完成队列:

!finalizequeue

在那里你会有一个对象列表,比如:

7aa143e0      166       20,584 System.Diagnostics.PerformanceCounter
79b5f6c8      543       21,720 System.Reflection.Emit.DynamicResolver
673893a8      953       22,872 System.Web.HttpResponseUnmanagedBufferElement

这可能对您有很大帮助。但您也可以检查这些对象 ( !do 7aa143e0 )、查找引用 ( !gcroot <address> ) 等。

关于c# - 我如何调查终结队列和终结幸存者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20121401/

相关文章:

javascript - 什么时候html元素多一些好还是少一些好?

java - 内联创建的 InputStream 是否被 GC 自动关闭?

python - 在覆盖大型 Python 对象的引用之前删除该引用有什么好处吗?

c# - 为什么 AppDomain.Unload() 在终结器中出错?

c# - Wpf:仅包含默认构造函数和 InitializeComponent() 调用的 xaml.cs 文件的替代方案

c# - 传递给其他类的 Expando 动态对象需要 Microsoft.CSharp.dll?

c# - 在 map/2d 数组中查找最近的(几何上)非零值

c# - 如何在 Linq 中使用 Sum()?

javascript - 从 k6 中的文件读取

c# - 这个 LINQ 性能从何而来?