.NET框架自动内存管理(3)

.NET框架自动内存管理(3)

 

3Finalize方法和对象的析构函数

 

System.Object对象提供Finalize方法,垃圾回收器在回收对象的内存之前,自动调用Finalize方法,然后回收对象占用的内存。默认情况下,Finalize方法不执行任何操作,如果需要让垃圾回收器在回收对象的内存之前执行对非托管资源等的清理操作,则派生类必须重写Finalize方法。

垃圾回收器使用“终止队列(Finalization List)”的内部结构跟踪重写Finalize方法的托管对象的生命周期:每次使用new运算符创建这种对象时,运行库从托管堆为该对象分配内存的同时,垃圾回收器还在“终止队列”中放置一个指向该对象的引用项。

当垃圾回收器执行内存回收时,它首先回收没有重写Finalize方法的不可访问对象,重写Finalize方法的不可访问对象在“终止队列”中的对应项被移除并放置到称为“freachable”的对象列表中。然后,垃圾回收器启动一个特殊的线程扫描并调用该对象列表中对象的Finalize方法,在Finalize方法中应用程序封装了清除非托管资源的代码。最后,将Finalize方法已调用的对象从列表中移出。 在下一次垃圾回收时,垃圾回收器将从“freachable”列表中移出的对象确定为垃圾,并回收其内存。

从上述垃圾回收过程可以看出,回收重写Finalize方法的对象使用的内存至少需要两次垃圾回收过程。因此重写Finalzie方法可能会对应用程序性能产生负面影响,应尽量避免使用它们。如果对象没有封装非托管资源,则不要轻易重写Finalize方法。

Object.Finalize方法被声明为受保护的(protected),这意味着Finalize方法保留给垃圾回收器自动调用,应用程序不应直接调用对象的Finalize方法。为保证基类的Finalize方法能够被垃圾回收器正确调用,在重写派生类的Finalize方法时,必须调用其基类的Finalize方法,这也是唯一一种允许在应用程序中调用Finalize的情况。

为确保在派生类的Finalize方法中调用基类的Finalize方法,C#提供了更加简洁的编程机制析构函数,虽然和C++类的析构函数有相同的名称和语法,但C#对象的析构函数意义却完全不同:并非所有的C#对象都需要析构函数,只有那些需要重写Finalize方法的对象才需要析构函数,而且在析构函数中将自动隐式地封装对基类Finalize方法的调用。例如,某个从BaseClass类派生的DerivedClass类的析构函数

~DerivedClass()

{

    // some lines of code to perform cleanup operations here

}

将被运行库自动隐式地翻译为以下代码

protected override void Finalize()

{

    try

    {

        // some lines of code to perform cleanup operations here

    }

    finally

    {

        base.Finalize();

    }

}

通过上述等效的代码结构确保了BaseClassFinalize方法总是能够被调用。因此C#编写的应用程序不直接重写基类的Finalize方法,而在需要重写基类的Finalize方法时为该类添加析构函数。

注意,垃圾回收器不能保证对象Finalize方法的调用顺序,因此在重写Finalize方法时不要引用任何其他托管对象,除非你能确信当前对象的Finalize方法被调用时,被引用的托管对象仍然在其生存期内。也就是说,如果对象A有一个指向对象B的引用,在A对象的Finalize方法中不应通过该引用对B对象作任何操作:

public class A {

    B b = new B();

    ......

~A() {

        // error

        b.MethodB();

}

}

public class B {

    public MethodB() {

        ......

    }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值