Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何调查终结队列和终结幸存者_C#_Performance_Garbage Collection_Dispose_Finalizer - Fatal编程技术网

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

C# 如何调查终结队列和终结幸存者,c#,performance,garbage-collection,dispose,finalizer,C#,Performance,Garbage Collection,Dispose,Finalizer,我正在调查我们的应用程序中的GC和内存使用情况,并注意到我们似乎有成千上万的终结幸存者。不幸的是,单是数字并不能真正告诉我我们是否有问题。然而,我们看到了一般的性能问题,而且内存使用率很高,并且在GC中花费了很多时间 理想情况下,我们无法控制的任何东西都不应进入最终确定队列。如果有,那就是一只虫子。有什么方法或工具可以用来检查这一点吗?我听过的一个建议是使用一个带有终结器的特殊构建,该终结器在每次执行时都会记录,但这是相当大的工作量,并且只适用于我们拥有其类型的对象。有没有更简单的方法 是否值得

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

理想情况下,我们无法控制的任何东西都不应进入最终确定队列。如果有,那就是一只虫子。有什么方法或工具可以用来检查这一点吗?我听过的一个建议是使用一个带有终结器的特殊构建,该终结器在每次执行时都会记录,但这是相当大的工作量,并且只适用于我们拥有其类型的对象。有没有更简单的方法

是否值得调查最终确定的幸存者?如果是,怎么做

是否值得调查最终确定的幸存者

是的,因为终结会影响性能和资源

如果是,怎么做

我建议代码检查

你的类型有终结器吗?如果是,这些措施是否正确实施?只有在直接控制非托管资源时,才需要终结器。如果你有一个终结器,你应该实现
IDisposable
并使用确定性清理。这样做将确保永远不会调用终结器。在
Dispose
方法中调用
GC.SuppressFinalize(this)
,可确保实例未完成,因为它已被释放

如果终结器位于库代码中,则这些类型将(或应该)实现
IDisposable
,并且您必须确定地处理这些实例,以确保永远不会调用它们的终结器。

与或扩展一起使用(取决于应用程序使用的版本)。不幸的是,目前还没有.NET4.5的版本。设置调试环境(安装WinDbg并复制到其文件夹Psscor文件)后,创建进程的转储。您可以轻松完成此操作,例如,借助工具:

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

!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
)等。

这可能不是您要查找的;但当我为CRM编写插件与outlook同步时,它总是消耗大量内存(随着时间的推移)。最后,我将应用程序分为两部分——一部分用于“与outlook通信”,另一部分用于“UI内容”;“与outlook的通信”部分是在单独的应用程序域中运行的-没有什么可以在应用程序域卸载后继续运行:)非常好-这看起来非常有用。我如何知道何时转储进程?例如,在windbg中,是否可以在查看长度的队列上设置条件中断?或者我只需要根据GC性能计数器等进行有根据的猜测吗?您可以配置procdump以根据特定性能计数器的阈值进行转储。
!finalizequeue
7aa143e0      166       20,584 System.Diagnostics.PerformanceCounter
79b5f6c8      543       21,720 System.Reflection.Emit.DynamicResolver
673893a8      953       22,872 System.Web.HttpResponseUnmanagedBufferElement