Finalizer线程对Object生命周期的影响

这期博客的话题有些沉重,我们来讨论.net对象的生生死死。首先,要给生死下个定义。在这篇博客中,每当谈及一个对象是死了的对象,指的是用户无法再获得其引用。这个定义是个对用户友好的定义,因为有很多时候,对象还残存在托管堆上,CLR依旧可以通过一些手法来获得它(比如RCW缓存中通过SyncBlk),但是这种“生不如死”的状态不在今天的讨论范围之内。
言归正传。众所周知,.NET倚仗GC管理分配在托管堆上的对象(也就是new出来的东东)。为了提供类似c++中析构函数的功能,也就是在对象即将死去的时候,执行一段用户代码来做一些清理工作,比如在一个COM组件上调用它的Release方法。
出于性能的考虑,CLR使用一个独立的线程来执行对象的Finalize方法,所以Finalize方法的执行并不是GC.Collect的一部分。下面一个程序验证了这个说法。

using System;
using System.Threading;

class ObjectWithFinalizer
{
    ~ObjectWithFinalizer()
    {
        Thread.Sleep(1000);
        Console.WriteLine("Finalize in thread {0}", Thread.CurrentThread.ManagedThreadId);
    }
}
class Program
{
    public static void Main()
    {
        Console.WriteLine("Run in thread {0}", Thread.CurrentThread.ManagedThreadId);
        ObjectWithFinalizer owf = new ObjectWithFinalizer();
        GC.Collect();
        Console.WriteLine("GC.Collect() end");
    }
}

Continue reading “Finalizer线程对Object生命周期的影响”