《C#与.NET3.0高级程序设计》读书笔记(三)

第五章(对象的生命周期)

一:类、对象和引用
    类是描述类型的实例在内存中什么样子的,对象是在托管堆中创建的类的实例,new返回的指向对象的引用,这个引用是存放在栈里的。

二:对象生命周期的基础
    1:法则:使用new关键字将一个对象分配在托管堆上,然后就不用再管。当一个对象从代码库的任何部分都不可达是,垃圾回收器会删除它。但不一定是在函数返回后立即回收。

    2:CIL的new指令
        在IL代码中是newobj,它执行时步骤如下:计算分配对象所需要的总内存数,如果托管堆中有足够空间,就调用构造函数分配,它的地址恰好是下一个对象指针的上一个位置,在将引用返回之前,移动下一个对象的指针。如果不够则进行垃圾回收。
        法则:如果托管堆没有足够的内存分配所请求的对象,就会进行垃圾回收。
        垃圾回收时会挂起当前进程的所有线程,以保证他们在回收时不会访问堆。

三:应用程序根的作用
    根就是一个存储位置,其中保存着对堆上一个对象的引用。垃圾回收时,没有根的对象认为是不可达的,CLR对建立“对象图”来判断。
    实际上,垃圾回收器使用了两个不同堆,一个专门用来存储非常大的对象,这个堆在回收周期中很少顾及。

四:对象的代
    1:一般分为三代,从0开始。分代的目的基于以下看法:对象在堆中存在的时间越长,它越应该被保留。一般先从第0代进行垃圾收集,需要时再向上代收集。
    2:System.GC。强制回收一般发生在:应用程序将要进入一段代码,后者不希望被可能的垃圾回收中断;应用程序刚刚分配非常多的对象,想尽可能的删除已请求的内存。
        调用Collect()后应该总是调用WaitForPendingFinalizers()。Collect()可以带参数,表示第几代。即使显式垃圾回收一次,CLR在幕后也执行了多次。

五:构建可终结对象
    1:System.Object定义的Finalize()虚方法默认什么都不做。重写的Finalize()是由垃圾回收器调用的,或者当APPDomain从内存卸载时被调用。
        重写Finalize()的唯一原因是:C#类使用了PInvoke或复杂的COM互操作性人物使用了非托管的资源。
        注意不能在结构类型上重写Finalize(),因为它是值类型。
    2:重写Finalize()
        不能使用override关键字,而应该使用类似析构函数的方式。因为C#编译器会在il代码中自动加上try语句,try语句中方的是你自定义的finalize要执行的操作,而finally语句里是它自动生成的一些错误检测代码,里面有执行基类的Finalize()。如果要用override关键字,就有了两个Finalize()函数。
    3:终结过程的细节
        一般只有在使用了非托管实体的类型时才重定义Finalize(),托管的自己会终结,没有意义再定义,并且终结时要花费时间的。
        在托管堆分配对象时,如果有自定义的Finalize方法,对象被标记为可终结的,同时一个指向该对象的指针被保存在“终结队列”里,“终结队列”是一个垃圾回收器维护的表,指向每一个在从堆上删除之前必须被终结的对象。当垃圾回收器确定到了从内存中释放一个对象的时间时,它检查终结队列上的每一项,并将对象从堆上复制到另一个“终结可达表”的托管结构上,下一个垃圾回收时产生另一个线程,为每一个可达表中的对象调用Finalize方法。因此,终结一个对象,至少要进行两次垃圾回收。

六:构建可处置对象
    1:结构和类类型都支持IDispoable,而Fianlize只适用于类类型。
    2:Dispose必须要被手工调用。Dispose()方法不但负责释放一个对象的非托管资源,还应该对任何它包含的可处置对象调用Dispose()。
    3:法则:如果对象支持IDispoable,总是要对直接创建的对象调用Dispose()。
    4:重用C#的using关键字,可以减少使用try,finally语句块。

七:构建可终结类型和可处置类型
    1:Dispose如果处理了非托管资源,应该调用GC.SuppressFinalize方法,通知CLR不再调用析构函数。
    2:微软有一个可处置模式的模板,可以让Finalize()和Dispose()和平相处。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值