• C#释放资源


     什么是资源? .NET 框架中如何访问资源?

    所谓的资源就是程序中可利用的数据,譬如:字符串、图片和任何二进制数据,包括任何类型的文件。

    在面向对象的环境中,每一个类型都标识为某些程序所用的资源,要想使用这些资源,必须为相应的类型分配一定的内存空间。

    访问一个资源需要如下几个步骤:

    1)分配内存空间: 调用中间语言(IL)中的newobj指令(使用new操作符时,将产生newobj指令),为某个特定资源的类型分配一定的内存空间。

    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程序块

    确定,在显示调用时

     

  • 相关阅读:
    《当程序员的那些狗日日子》(二十七)大项目
    《当程序员的那些狗日日子》(四十二)内心的挣扎
    《当程序员的那些狗日日子》(二十一)加班,加班
    《当程序员的那些狗日日子》(三十四)人事变动
    《当程序员的那些狗日日子》(五十二)同学情与差距
    《当程序员的那些狗日日子》(四十四)是办公室还是牢房
    《当程序员的那些狗日日子》(四十七)躁动的空气
    《当程序员的那些狗日日子》(三十七)黯然离去
    《当程序员的那些狗日日子》(十六)告别
    《当程序员的那些狗日日子》(二十三)死在了今天的晚上
  • 原文地址:https://www.cnblogs.com/zhayunjia/p/7365692.html
Copyright © 2020-2023  润新知