6

我需要优化我的应用程序的内存使用。所以我使用了 .net 性能分析器......但是我的应用程序中的一些引用仍然存在,即使我强制它收集,GC 也不会收集它。

活动的引用是“终结句柄”类型。我不知道该怎么做才能删除这种参考......请帮忙。

这张照片就是我的意思

4

1 回答 1

4

这不是内存泄漏,只是 AMProLibrary 的作者的草率编码。

正如您所观察到的,分析器告诉您引用的对象是“完成句柄”类型。这意味着它来自终结器队列。终结器队列是 .NET 垃圾收集器用来保存所有实现终结器方法的对象。终结器是用于确保在垃圾回收期间正确释放非托管资源的机制。包含非托管资源的对象实现了该IDisposable模式,包括Finalize释放非托管资源的方法。当垃圾收集器处理“可终结的”对象(如对象标头中的某个位的值所指示的)时,它将它们移动到终结器队列中。在收集期间,GC 遍历终结器队列并调用Finalize每个对象的方法。

库的作者显然没有做的是GC.SuppressFinalize()从方法内部调用Dispose。这通常通过清除对象标头中的“finalizable”位从终结器队列中删除对象,并指示Finalize不需要调用该方法。

GC.WaitForPendingFinalizers出于测试目的,您可以通过调用该函数来强制运行终结器。例如:

System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect();

但是,您实际上不应该在生产应用程序中使用这样的代码。强制收集很少有意义。这只会证明上述假设的有效性。

通常,您不应依赖终结器来释放非托管资源。所有实现的对象都IDisposable应该由您的代码显式处理,或者通过手动调用Dispose方法,或者最好将它们的创建包装在一个块中,该块将在退出块的范围时using自动调用。Dispose

于 2016-11-27T13:45:25.617 回答