如何调查终结队列和终结幸存者

Rob*_*Rob 3 c# performance garbage-collection dispose finalizer

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

理想情况下,我们无法控制的任何内容都应该进入终结队列.这是一个错误,如果它.我可以使用一些方法或工具来检查这个吗?我听到的一个建议是使用终结器进行特殊构建,只要它们被执行就会记录,但这需要付出很多努力,并且只适用于我们拥有类型的对象.有没有更简单的方法?

是否值得调查最终幸存者?如果是这样,怎么样?

Kon*_*osa 5

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

procdump -ma <PID>
Run Code Online (Sandbox Code Playgroud)

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

.load psscor4
Run Code Online (Sandbox Code Playgroud)

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

!symfix
Run Code Online (Sandbox Code Playgroud)

从现在开始,您应该可以访问很多非常有趣的命令(寻找!help列出它们).要查看终结队列:

!finalizequeue
Run Code Online (Sandbox Code Playgroud)

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

7aa143e0      166       20,584 System.Diagnostics.PerformanceCounter
79b5f6c8      543       21,720 System.Reflection.Emit.DynamicResolver
673893a8      953       22,872 System.Web.HttpResponseUnmanagedBufferElement
Run Code Online (Sandbox Code Playgroud)

这可能对你有很大的帮助.但你也可以检查那些对象(!do 7aa143e0),找到引用(!gcroot <address>)等.