gpt4 book ai didi

c# - 终结句柄保留在内存中。如何删除此引用?

转载 作者:太空狗 更新时间:2023-10-30 01:31:34 25 4
gpt4 key购买 nike

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

活着的引用是“终结句柄”类型。我不知道如何删除这种引用....请帮忙。

this picture is what I mean

最佳答案

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

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

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

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

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

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

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

关于c# - 终结句柄保留在内存中。如何删除此引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40828571/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com