什么是资源? .NET 框架中如何访问资源?算法
所谓的资源就是程序中可利用的数据,譬如:字符串、图片和任何二进制数据,包括任何类型的文件。数据库
在面向对象的环境中,每个类型都标识为某些程序所用的资源,要想使用这些资源,必须为相应的类型分配必定的内存空间。框架
访问一个资源须要以下几个步骤:函数
1)分配内存空间: 调用中间语言(IL)中的newobj指令(使用new操做符时,将产生newobj指令),为某个特定资源的类型分配必定的内存空间。spa
2) 初始化内存: 一个类型的实例构造器负责这样的初始化工做。操作系统
3)使用资源: 经过访问类型成员来使用资源。根据须要会有反复。线程
4)销毁资源: 执行清理工做。对象
5)释放内存: 托管堆上的内存由GC全权负责, 值引用的在栈上的内存会随着栈空间的消亡而自动消失。继承
1. 什么是托管资源,非托管资源?接口
托管资源是由CLR全权负责的资源,CLR不负责的资源位非托管资源。
对于托管资源经过GC自动回收。
对于非托管资源GC管理,经过代码调用手动进行清除。
2. 什么是垃圾, 什么是垃圾回收?
Net类型分为两大类,一个就是值类型,另外一个就是引用类型。前者是分配在栈上,并不须要GC回收;后者是分配在堆上,所以它的内存释放和回收须要经过GC来完成,
那么只有被称为垃圾的对象才能被GC回收。也就是说,一个引用类型对象所占用的内存须要被GC回收,须要先成为垃圾。
那么.Net如何断定一个引用类型对象是垃圾呢,.Net的判断很简单,只要断定此对象或者其包含的子对象没有任何引用是有效的,那么系统就认为它是垃圾。
内存的释放和回收须要伴随着程序的运行,所以系统为GC安排了独立的线程。那么GC的工做大体是,查询内存中对象是否成为垃圾,而后对垃圾进行释放和回收。
那么对于GC对于内存回收采起了必定的优先算法进行轮循回收内存资源。
其次,对于内存中的垃圾分为两种,一种是须要调用对象的析构函数,另外一种是不须要调用的。
GC对于前者的回收须要经过两步完成,第一步是调用对象的析构函数,第二步是回收内存,可是要注意这两步不是在GC一次轮循完成,即须要两次轮循;相对于后者,则只是回收内存。
3. 如何正确的释放资源?
托管的内存资源,这是不须要咱们操心的,系统已经为咱们进行管理了。
对于非托管的资源,这里再重申一下,就是Stream,数据库的链接,GDI+的相关对象,还有Com对象等等这些操做系统资源,须要咱们手动去释放。
如何去释放,应该把这些操做放到哪里比较好呢。.Net提供了三种方法,也是最多见的三种,大体以下:
1. 析构函数;
2. 继承IDisposable接口,实现Dispose方法;
3. 提供Close方法。
|
析构函数 |
Dispose方法 |
Close方法 |
意义 |
销毁对象 |
销毁对象 |
关闭对象资源 |
调用方式 |
不能被显示调用,会被GC调用 |
须要显示调用 或者经过using语句 |
须要显示调用 |
调用时机 |
不肯定 |
肯定,在显示调用或者离开using程序块 |
肯定,在显示调用时 |