【问题标题】:GC.Collect does not call IronPython destructorGC.Collect 不调用 IronPython 析构函数
【发布时间】:2015-12-20 22:11:05
【问题描述】:

我有一个简单的 IronPython 类,它实现了一个析构函数 (__del__) 并向控制台写入了一些东西 在里面。如果不再引用该实例并且我出于测试目的调用GC.Collect,则将永远不会调用析构函数。它是否正确? DLR/IP 在 clr/gc 之上是否有自己的内存管理?

【问题讨论】:

  • 不确定 Iron Python 中的析构函数,但如果它们类似于 C# 中的终结器,那么这可能是一些不错的阅读 ericlippert.com/2015/05/18/…
  • 我不是积极的,也不要引用我的话(不再需要在.Net中处理析构函数的结果)但我认为即使在纯 C# 应用程序中调用 GC .Collect 不能保证 GC 会立即触发。

标签: c# garbage-collection clr ironpython dynamic-language-runtime


【解决方案1】:

这可能是一个比您意识到的更广泛的问题。

具有终结器的类的典型行为是 GC 将在收集时将项目移动到终结器队列中。对象队列是单独处理的(尽管您可以调用GC.WaitForPendingFinalizers() 来阻止它直到它完成)。这意味着该对象仍然是根对象(即使不是来自您的代码,也有来自终结器队列的引用!)因此通常会在 GC 中存活并被提升到下一代。

出于这个原因,您可能需要在清理您的项目之前两次进行 GC。这也意味着终结器将根据定义发生在您收集后的任意时间。但是,如果你调用 GC.WaitForPendingFinalizers(),你应该会看到你的终结器被调用。

为避免所有这些不良行为,通常实现IDisposable 接口来显式处理非托管资源的清理。如果您查看典型的example implementation from documentation,您会看到Dispose 方法通常调用GC.SuppressFinalize(this)。这意味着,如果您在代码中干净地处理对象,则根本不需要调用终结器。

【讨论】:

  • 感谢您的回答。即使使用GC.WaitForPendingFinalizers() + GC.Collect 也不会调用构造函数。 (在不同的变化和多次使用它)这也只是为了测试目的,dlr 如何反应/工作。感谢您的精彩而详细的回答!
猜你喜欢
  • 2015-03-29
  • 1970-01-01
  • 2015-02-21
  • 2011-04-16
  • 2019-01-09
  • 2023-03-31
  • 2015-10-07
相关资源
最近更新 更多