C# 商店';这';定稿时
如何定义在类终结期间存储“this”的代码?垃圾收集器应该如何工作(如果在某处定义) 在我看来,GC应该多次完成类实例,并且下面的测试应用程序将打印“66”,但是终结器只执行一次,导致应用程序打印“6” 几行代码: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; }
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而言——完全处于活动状态。