.net 使用终结操作来释放本地资源

大多数类型只需内存就可以正常工作。但是,也有一些类型除了要使用内存,还要使用本地资源。

例如,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方法,本地资源就得不到关闭,导致资源泄漏,直至进程终止。进程终止时,这些本地资源才会被操作系统回收。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值