非托管资源的回收问题

来源:互联网 发布:linux重新启动命令 编辑:程序博客网 时间:2024/06/06 22:02
 
在WinForm编程里面,我们经常会使用dispose()方法来释放对象所占的资源,实际上这是在释放非托管资源的所占用的内存。开始讨论问题前,有必要把托管资源和非托管资源进行定义,在网上看到很多定义都只是停留在表面意义,这样对学习者的启示远远不如举个例子方便。下面一段是我看到的最好的一段定义:
“最常见的一类非托管资源就是包装操作系统资源的对象,例如文件,窗口或网络连接,对于这类资源虽然垃圾回收器可以跟踪封装非托管资源的对象的生存期,但它不了解具体如何清理这些资源。还好.net Framework提供了Finalize()方法,它允许在垃圾回收器回收该类资源时,适当的清理非托管资源。如果在MSDN Library 中搜索Finalize将会发现很多类似的主题,这里列举几种常见的非托管资源:ApplicationContext,Brush,Component,ComponentDesigner,Container,Context,Cursor,FileStream,Font,Icon,Image,Matrix,Object,OdbcDataReader,OleDBDataReader,Pen,Regex,Socket,StreamWriter,Timer,Tooltip等等资源。可能在使用的时候很多都没有注意到!关于托管资源,就不用说了撒,像简单的int,string,float,DateTime等等,.net中超过80%的资源都是托管资源。”
从上面的定义可以看出,包括Form在内的一系列控件都属于非托管资源(或非受控资源),而很多人往往认为Windows Form控件是托管资源(网络上也有持相反观点者,认为实现了IDisposable接口的都是托管资源,将非托管资源进行包装就是通过实现IDispoable接口的这一方式完成的)。据我观察,.net里的非托管资源都是有dispose()方法的,不知道这能否成为识别.net framework中托管或非托管资源的标准(但是像Object类自身却并没有实现IDosposable接口,需要拆箱后判断是否实现了次接口)。我们讨论的资源回收也仅限于非托管资源的回收,因为托管资源的回收使用者是操纵不了的。
对非托管资源的回收,使通过finalize()方法实现的,但是在实际操作中,很少有人通过该函数手动释放非托管资源,而一般用来自动释放非托管资源。但是在很多情况下,有必要对非托管资源进行手动释放,原因主要有两个:第一,垃圾回收器(GC)并不能及时清理非托管资源,非托管资源的自动清理,不定时也没有顺序;第二,依靠GC来自动回收非托管资源需要调用finalize()函数,开销稍大。基于这两个原因,当系统对资源需求较高时,最好对非托管资源实现手动回收机制。
这里有一篇比较完整的例子,大家可以看一看。http://www.cnblogs.com/chinhr/archive/2007/12/07/986955.html
原创粉丝点击