【问题标题】:Who calls whom?谁叫谁?
【发布时间】:2014-02-06 09:28:09
【问题描述】:

我对 msdn 上这两个看似矛盾的陈述感到困惑..

1) 当类包含析构函数时,会在 Finalize 队列中创建一个条目。当析构函数被调用时,垃圾收集器被调用来处理队列。

2) 程序员无法控制何时调用析构函数,因为这是由垃圾收集器决定的。垃圾收集器检查应用程序不再使用的对象。如果它认为一个对象可以销毁,它会调用析构函数(如果有的话)并回收用于存储该对象的内存。

在第一条语句中,我理解析构函数调用 ---> 垃圾收集器 而从第二条语句中我了解到垃圾收集器调用--->析构函数

??

更新:link

【问题讨论】:

  • 你有第一个语句的链接吗?
  • 引用一下,这些语句出自哪里??

标签: c# garbage-collection destructor finalize


【解决方案1】:

首先垃圾收集器确定一个对象符合收集条件。

如果对象需要终结,则将其放入终结队列;它现在又活了,因为队列是根。

然后终结器线程运行,将对象标记为不再需要终结器,并运行终结器。

如果在终结器结束时对象仍然是死的,那么当 GC 稍后再次运行时,它会发现有一个不需要终结的死对象,并清理它。

【讨论】:

  • 您的意思是 GC 调用析构函数,这反过来又导致 finalize 被调用。finilize 执行将其标记为“不需要终结”.. 在下一次运行期间 gc 将其删除。所以它的 GC 调用 ---> Destructor ??
  • 你的意思是第一次GC调用终结器,当GC只运行时它会回收内存?这是否意味着带有析构函数的对象至少需要 2 个 GC 周期才能被清理?还是一个接一个地立即发生?
  • @SriramSakthivel:是的,可终结的对象 (1) 被提升到下一代,并且 (2) 直到 second GC 发现它们已死时才真正释放。如果您不喜欢这样,那么不要制作析构函数
  • @EricLippert ,考虑这个 .. “析构函数隐式调用对象基类的 Finalize。因此,析构函数代码隐式转换为以下代码:” protected override void Finalize() { try { // 清理语句... } finally { base.Finalize();所以翻译后的代码中实际上没有析构函数?和 GC 导致最终确定?
  • @EricLippert 非常感谢,睁开眼睛,我今天学到了一些新东西。 :) ;还有一个问题,那么即使在Finalized 之后,一个对象是否可能还活着? PS:I read your answer here already
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-15
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
相关资源
最近更新 更多