C# 商店';这';定稿时

C# 商店';这';定稿时,c#,garbage-collection,.net-2.0,finalizer,C#,Garbage Collection,.net 2.0,Finalizer,如何定义在类终结期间存储“this”的代码?垃圾收集器应该如何工作(如果在某处定义) 在我看来,GC应该多次完成类实例,并且下面的测试应用程序将打印“66”,但是终结器只执行一次,导致应用程序打印“6” 几行代码: using System; namespace Test { class Finalized { ~Finalized() { Program.mFinalized = this; }

如何定义在类终结期间存储“this”的代码?垃圾收集器应该如何工作(如果在某处定义)

在我看来,GC应该多次完成类实例,并且下面的测试应用程序将打印“66”,但是终结器只执行一次,导致应用程序打印“6”

几行代码:

using System;

namespace Test
{
    class Finalized
    {
        ~Finalized()
        {
            Program.mFinalized = this;
        }

        public int X = 5;
    }

    class Program
    {
        public static Finalized mFinalized = null;

        static void Main(string[] args)
        {
            Finalized asd = new Finalized();
            asd.X = 6;
            asd = null;
            GC.Collect();

            if (mFinalized != null)
                Console.Write("{0}", mFinalized.X);

            mFinalized = null;
            GC.Collect();

            if (mFinalized != null)
                Console.Write("{0}", mFinalized.X);
        }
    }
}
我想做的是理解终结器是如何管理实例内存的。在我的应用程序中,可能需要再次重用实例引用以进行进一步处理

很明显,终结器不会“释放”内存(至少在我的测试应用程序中)。内存块是否可以用于其他目的?甚至被释放?如果不是,那就是内存泄漏还是什么


现在,我比以前更困惑了。

我对复活物体的任何好用途都感兴趣

MSDN声明“复活很少有好的用途,如果可能的话,你真的应该避免它”。
此外,比尔·瓦格纳(Bill Wagner)在其有效的C#中说:“你不能让这种构造可靠地工作,不要尝试。”。但是这本书已经有2年的历史了,所以可能有什么改变了?

这是因为复活。通过在终结期间将对象存储在另一个变量中(将
分配给一个变量),就GC而言,可以恢复obejct实例。您可以在.NET中恢复您的对象,实际上您可以使GC多次完成该对象,但您必须通过显式请求它


有关详细信息,请参阅。

只调用一次终结器。您可以自由地将自己分配到某个地方,并防止对象被垃圾收集。但是,一旦对象再次可用于GC,它就不会运行终结器。

GC.Collect执行扫描,使用终结器对任何对象进行特殊的装箱,而不收集它们。一旦这些终结器对象被终结,GC就会再次在这些对象上运行。如果它们不再符合收集条件(通过重新根目录,就像您所做的那样),那么就这样吧。通常,终结器只运行一次,但是IIRC,您可以请求它再次运行。

根据我的经验,如果使用终结器,您总是会出错。我知道有些情况下需要使用终结器,但我想不出有哪种情况会在终结器中写入控制台(或做任何有明显副作用的事情)。@KendallFrey:总是错误的,不是终结器。即使我同意你的观点,我的案例也迫使我对此进行调查。因为Freachable队列是一个根对象,所以所有可终结对象都会在GC循环结束之前复活,否则它们将被销毁。一旦运行终结器,FReachable队列中的条目将被删除,如果不存在其他根引用,对象将再次失效。然而,从发现对象没有引用到它的终结器运行的时间,对象将——就GC而言——完全处于活动状态。