gpt4 book ai didi

.net - Finalizer Queue 和 Control+ThreadMethodEntry 是什么?

转载 作者:行者123 更新时间:2023-12-02 06:54:22 24 4
gpt4 key购买 nike

我有一个 WindowsForms 应用程序似乎存在内存泄漏,因此我使用 Redgate 的 ANTS Memory Profiler 来查看我怀疑的对象,发现它们仅由 Finalizer Queue 上已有的对象所持有。太好了,到底什么是终结器队列?你能给我指出最好的定义吗?您能分享一些轶事建议吗?

此外,Finalizer 队列上的所有根 GC 对象都是名为“caller”的 System.Windows.Forms.Control+ThreadMethodEntry 对象的实例。我看到它涉及多线程UI交互,但除此之外我不知道太多。请原谅我明显的懒惰和承认的无知,但这些资源都隐藏在供应商的组件中。我正在与供应商讨论这些问题,但我需要一些指导来加快对话速度。您能给我指出 ThreadMethodEntry 最有用的定义吗?有什么轶事建议吗?

此外,我是否应该关心终结器队列中的这些对象?

更新:Red Gate article很有帮助。

最佳答案

终结器队列保存所有定义了终结器方法的对象。回想一下,终结器是一种收集非托管资源(例如句柄)的方法。当垃圾收集器收集垃圾时,它将带有终结器的任何对象移动到终结器队列中。在稍后的某个时刻——根据内存压力、GC 启发式和月相——当垃圾收集器决定收集这些对象时,它会沿着队列走下去并运行终结器。

过去处理过内存泄漏问题,在终结器队列中看到一堆供应商的对象可能是草率的代码,但这并不表示存在内存泄漏。通常,好的代码会公开一个 Dispose 方法,该方法将收集托管和非托管资源,并通过 GC.SuppressFinalize() 将其自身从终结器队列中删除。因此,如果供应商的对象确实实现了 Dispose 方法,而您的代码没有调用它,则可能会导致终结器队列中出现一堆对象。

您是否尝试过在 ANTS 中创建两个时间点之间的快照并比较它们之间创建的对象?这可以帮助您识别任何正在泄漏的托管对象。

此外,如果您想查看运行终结器时内存是否消失,请尝试使用以下方法进行测试:

System.GC.Collect();System.GC.WaitForPendingFinalizers(); // this method may block while it runs the finalizersSystem.GC.Collect();

我不建议正常运行此代码。如果您刚刚完成了大量工作并产生了大量垃圾,您可能想要运行它。例如,在我们的应用程序中,我们的函数之一可能会创建大约 350 MB 的垃圾,这些垃圾在关闭 MDI 窗口后就会被浪费掉。由于已知这会留下大量垃圾,因此我们手动强制垃圾收集。

另请注意,基本 Windows.Forms 代码中有一个低级属性缓存,它将保留最后打开的模式对话框。这可能是内存泄漏的根源。摆脱此引用的一种可靠方法是强制显示另一个简单的对话框,然后运行上面的 GC 代码。

关于.net - Finalizer Queue 和 Control+ThreadMethodEntry 是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1268525/

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