赞
踩
大多数类型只需内存就可以正常工作。但是,也有一些类型除了要使用内存,还要使用本地资源。
例如,System.IO.FileStream 类型需要打开一个文件(本地资源)并保存文件的句柄。然后该类型的Read和Write方法用该句柄来操作文件。类似地,System.Threading.Mutex类型要打开一个Windows互斥体内核对象(本地资源)并保存其句柄,并在调用Mutex的方法时使用该句柄。
终止(finalization)是CLR提供的一种机制,允许对象在垃圾回收期回收其内存之前执行一些得体的清理工作。任何包装了本地资源(例如文件、网络连接、套接字、互斥体或其他类型)的类型都必须支持终结操作。简单地说,类型实现了一个命名为Finalize的方法。当垃圾回收器判断一个对象是垃圾时,会调用对象的Finalize 方法(如果有的话)。可以这样理解:实现了Finalize的方法的任何类型实际上是在说,它的所有对象都希望在“被处决之前吃上最后一餐”。
Microsoft的C#团队认为,Finalize方法是在编程语言中需要特殊语法的一种方法(类似于C#要求用特殊的语法定义构造器)。因此,在C#中,必须在类名前加~符号来定义Finalize方法,如下例所示:
internal sealed class SomeType{
//这是一个Finalize方法
~SomeType(){
//这里的代码会进入Finalize方法
}
}
编译上述代码,用IL Dasm.exe检查得到的程序集,会发现C#编译器实际是在模块的元数据中生成了一个名为Finalize的protected override方法。查看Finalize的IL代码,会发现方法主体的代码被放到一个try块中,finally块则放入一个对base.Finalize的调用。
实现FInalize方法时,一般都会调用Win32 CloseHandle函数,并向该函数传递本地资源的句柄。例如FileStream 类型定义了一个文件句柄字段,它表示了本地资源。 FileStream类型还定义了一个Finalize方法,它在内部调用CloseHandle函数,并向它传递文件句柄字段。这就确保了在托管的FileStream对象被确定为垃圾后,本地文件句柄会得以关闭。如果包装了本地资源的类型没有定义Finalize方法,本地资源就得不到关闭,导致资源泄漏,直至进程终止。进程终止时,这些本地资源才会被操作系统回收。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。