代码之家  ›  专栏  ›  技术社区  ›  flipdoubt

什么是Finalizer队列和Control+ThreadMethodEntry?

  •  10
  • flipdoubt  · 技术社区  · 17 年前

    Red Gate article

    3 回复  |  直到 17 年前
        1
  •  16
  •   Paul Williams    17 年前

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

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

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

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

    另请注意,基本Windows中有一个低级属性缓存。表单代码将保留最后打开的模态对话框。这可能是内存泄漏的原因。摆脱此引用的一种可靠方法是强制出现另一个简单的对话框,然后运行上述GC代码。

        2
  •  1
  •   cedrou    17 年前

    终结器队列是一个队列,其中不再使用的对象实例正在等待GC的终结。此队列中的所有对象都将被最终确定,您的内存泄漏可能不是直接来自这些对象之一。但是,其中一个对象可能不会释放其所有非托管资源。

    ThreadMethodEntry类是IAsyncResult的实现,该类的实例通常在调用异步操作时创建,例如使用Invoke更新UI或使用Begin*/End*方法。

        3
  •  0
  •   Tim Cooper    14 年前

    Here's 一篇描述类似问题的好博客文章。在更技术的层面上,您可以考虑使用SOS.dll(博客文章对此进行了描述)和 Sosex.dll 以帮助您了解为什么这些ThreadMethodEntry对象在内存中挂起。这些Winchester扩展中有一些命令可以跟踪内存中引用特定对象的其他对象。