如何定义在课程定稿期间存储'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);
}
}
}
我要做的是了解终结器如何管理实例内存。在我的应用程序中可能需要再次重用实例引用以进行进一步处理。
很明显终结器不会“释放”内存(至少在我的测试应用程序中)。可以将内存块重用于其他目的吗?甚至解放了?如果不是,那会是内存泄漏还是什么?
现在,我比以前更加困惑。
答案 0 :(得分:8)
这是由于复活。通过在最终确定期间将对象存储在另一个变量中(将this
分配给变量),就GC而言,复活 obejct实例。您可以在.NET中恢复您的对象,并且您实际上可以使GC多次完成对象,但您必须通过GC.ReRegisterForFinalize明确请求它。
有关详细信息,请参阅Automatic Memory Management in the Microsoft .NET Framework。
答案 1 :(得分:4)
GC.Collect使用终结器进行扫描,特殊套管任何对象,不收集它们。一旦这些终结器对象完成,GC就会再次运行这些对象。如果他们不再有资格收集(通过重新生根,就像你一样),那就这样吧。通常终结器只运行一次,但是IIRC,你可以请求它再次运行。
答案 2 :(得分:0)
我对复活对象的任何好用都很感兴趣。
MSDN声明“复活的好用途很少,如果可能,你真的应该避免使用它”。 Bill Wagner在他的Effective C#中也说“你不能让这种结构可靠地工作。不要试试”。但是这本书已有2年了,所以可能会有所改变?
答案 3 :(得分:0)
Finalizer只被调用一次。您可以自由地将self分配给某个地方,并防止该对象被垃圾收集。但是,一旦该对象再次可用于GC,它就不会运行终结器。