当前位置:   article > 正文

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

.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方法
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

编译上述代码,用IL Dasm.exe检查得到的程序集,会发现C#编译器实际是在模块的元数据中生成了一个名为Finalize的protected override方法。查看Finalize的IL代码,会发现方法主体的代码被放到一个try块中,finally块则放入一个对base.Finalize的调用。

实现FInalize方法时,一般都会调用Win32 CloseHandle函数,并向该函数传递本地资源的句柄。例如FileStream 类型定义了一个文件句柄字段,它表示了本地资源。 FileStream类型还定义了一个Finalize方法,它在内部调用CloseHandle函数,并向它传递文件句柄字段。这就确保了在托管的FileStream对象被确定为垃圾后,本地文件句柄会得以关闭。如果包装了本地资源的类型没有定义Finalize方法,本地资源就得不到关闭,导致资源泄漏,直至进程终止。进程终止时,这些本地资源才会被操作系统回收。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/590061
推荐阅读
相关标签
  

闽ICP备14008679号