C#托管资源与非托管资源
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C#托管资源与⾮托管资源
在.net 编程环境中,系统的资源分为托管资源和⾮托管资源。
托管资源:
Net平台中,CLR为程序员提供了⼀种很好的内存管理机制,使得程序员在编写代码时不要显式的去释放⾃⼰使⽤的内存资源(这些在先前C和C++中是需要程序员⾃⼰去显式的释放的)。
这种管理机制称为GC(garbage collection)。
GC的作⽤是很明显的,当系统内存资源匮乏时,它就会被激发,然后⾃动的去释放那些没有被使⽤的托管资源(也就是程序员没有显式释放的对象)。
所以托管就是.net framework 负责帮你管理内存及资源释放,不需要⾃⼰控制,当然对象只针对托管资源(部分引⽤类型), 不回收⾮托管资源。
像数组,⽤户定义的类、接⼝、委托,object,字符串等引⽤类型,栈上保存着⼀个地址⽽已,当栈释放后,即使对象已经没有⽤了,但堆上分配的内存还在,只能等GC收集时才能真正释放;但注意int,string,float,DateTime之类的值类型,GC会⾃动释放他们占⽤的内
存,不需要GC来回收释放
那么⾮托管的资源怎么释放回收呢?
⾮托管资源:
对于⾮托管资源,GC只能跟踪⾮托管资源的⽣存期,⽽不知道如何去释放它。
这样就会出现当资源⽤尽时就不能提供资源能够提供的服务,windows的运⾏速度就会变慢。
⽐如当你链接了数据库,⽤完后你没有显式的释放数据库资源,如果还是不断的申请数据库资源,那么到⼀定时候程序就会抛出⼀个异常。
所以,当我们在类中封装了对⾮托管资源的操作时,我们就需要显式,或者是隐式的释放这些资源。
在.Net中释放⾮托管资源主要有2种⽅式,Dispose,Finalize,⽽Finalize和Dispose⽅法分别就是隐式和显式操作中分别使⽤到的⽅法。
例如⽂件流,数据库的连接,系统的窗⼝句柄,打印机资源等等,当你读取⽂件之后,就需要对各种Stream进⾏Dispose等操作。
⽐如SqlDataReader 读取数据完毕之后,需要 reader.Dispose();等
Finalize⼀般情况下⽤于基类不带close⽅法或者不带Dispose显式⽅法的类,也就是说,在Finalize过程中我们需要隐式的去实现⾮托管资源的释放,然后系统会在Finalize过程完成后,⾃⼰的去释放托管资源。
在.NET中应该尽可能的少⽤析构函数释放资源,MSDN2上有这样⼀段话:实现 Finalize ⽅法或析构函数对性能可能会有负⾯影响,因此应避免不必要地使⽤它们。
⽤ Finalize ⽅法回收对象使⽤的内存需要⾄少两次垃圾回收。
所以有析构函数的对象,需要两次,第⼀次调⽤析构函数,第⼆次删除对象。
⽽且在析构函数中包含⼤量的释放资源代码,会降低垃圾回收器的⼯作效率,影响性能。
所以对于包含⾮托管资源的对象,最好及时的调⽤Dispose()⽅法来回收资源,⽽不是依赖垃圾回收器。