我需要优化我的应用程序的内存使用。所以我使用了 .net 性能分析器......但是我的应用程序中的一些引用仍然存在,即使我强制它收集,GC 也不会收集它。
活动的引用是“终结句柄”类型。我不知道该怎么做才能删除这种参考......请帮忙。
我需要优化我的应用程序的内存使用。所以我使用了 .net 性能分析器......但是我的应用程序中的一些引用仍然存在,即使我强制它收集,GC 也不会收集它。
活动的引用是“终结句柄”类型。我不知道该怎么做才能删除这种参考......请帮忙。
这不是内存泄漏,只是 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