• .NET.GC学习总结


    GC机制
    〉根  对象托管堆  (~)终止化链表 终止化队列
    〉GC对托管对象有很好的清理工作,但对象使用了非托管资源时,我们需要一些机制来帮助GC做好清理工作。
     

    1:析构函数~   Finalize()完成器
     。Object 保护方法Finalize() 可以被继承对象重写,一旦被重写(用~函数),GC就认为它是含完成器的对象。
     。一个对象的~编译后成proteced override void Finalize(){try{...清理工作..}catch{base.Finalize()}}
                  [.net规定的机制 要保证调用了base.Finalize()父类的非托管清理 如果是多层继承,每层都用这个结构]
     。 Finalize()方法由GC调用
     。对重写了 Finalize() 的类 在“垃圾回收”回收 要经过终止化链表 终止化队列的操作后[因为它含清理代码] 第二次才被GC回收
     。缺点:用该方式来清理非托管资源 时间上具有不确定性能,而且GC回收要经过两次

    2:Dispose() :在程序中可调用显示清理
     。 优点:可由程序员可控制
     。public void Dispose()
       {
        // 清理代码 比如说释放非托管资源

    class DisposeFinalizeClass:System.IDisopose{

     
    private bool isDispose=false;//用该变量标示该类是否已经Dispose
     
    //清理资源的代码在Dispose(bool)方法中
     protected virtual void Dispose(bool disposing){
       
    if(!this.isDispose){//表示该对象有没有调用过Dipose方法,没有的话执行下面的代码
         if(diposing){//表示要通过调用对象的Dipose方法来清理资源
          
    //Code清理该对象关联的托管对象,通过调用它们的Dispose()方法
         }

         
    //Code清理非托管资源
       }

       
    this.isDispose=true;//表示已经清理了
     }

     
    public void Dispose(){
      
    this.Dispose(true);
      System.GC.SuppressFinalize(
    this);//告诉GC我已经清理了,你不必须使用完成器了
     }


     
    ~DisposeFinalizeClass{
      
    this.Dispose(false);//如果没有通过Dispose清理,通过传递False也可以清理非托管资源
     }

     
    }


    说明:
    1 如果要客户调用对象的Dipose() 来清理资源的话既清理非托管资源又要清理该对象用到的托管资源调用它们的Dipose() ,变量isDipose保证不会对象清理后,又被调用来执行清理。
        
    2 :如果用户没有用Dispose或是忘了用它来清理资源的话,GC最后会完成清理工作的,不过它不会去清理该对象使用的托管资源 ,因为GC不知掉它们的状态。我们也不必关心是否它们不会被清理,因为如果它们包含非托管资源的话,它们也会定义成以上的结构,也会逐一的被清理。

     
    3 protected virtual void Dispose(bool disposing) 可以被子类重写重写语句中
       
    {//子类清理资源
        base.Dipsose(disposing)//调用基类清理工作  
       }
      
      以上结构能保证继承的各层都能调用清理资源的代码
      Component
    ---Control-----Form  就是应该这种结构


        //如果对象有~ (Finalize())还要执行下列代码
         System.GC.SuppressFinalize(this);//告诉GC不要执行调用指定对象的完成器了(Finalize),我已经处理了
       }

     。//使用uing 语句的对象必须实现了System.IDisposable
      using (Class_Dispose cd=new Class_Dispose())
       {
       //使用cd的行为
       //即时出现异常 uing 语句也会调用 cd的Dispose方法来清理非托管的代码
       //其实uing的结构就是try{} finally{对象.Dispose();}
       **出现异常,程序会跳出对象作用域,这样对象.Dispose()执行不了,但用try()catch()finally{}就是保证对象.Dispose()也能执行
       }

      。关于继承体系中各层含要清理的代码如何实现   Dispose();    protected virtual Dispose(bool)
        个人觉得应该是这样 最低基类{ Dispose{this.Dispose(bool)}}   每层子类 Dispose(bool){....base.Dispose(bool)}
         如:Component中Dispose()和proteced virtual Dispose(bool)--- Control中的Dispose(bool)---Form类中protected Dispose(bool)
        ?MyForm类重写protected Dispose(bool)在什么时候调用Dispose呢
        ?bool的值又是怎么决定的呢
        

    3:Dispose()和Finalize双重保险机制

    4: 最后是关于close()与Dispose()

  • 相关阅读:
    【转】c++继承中的内存布局
    Google 开源项目风格指南
    常见面试题
    PHP7.1中使用openssl替换mcrypt
    phpunit实践笔记
    PHP的错误处理
    CI的扩展机制
    #CI的MVC实现
    Laravel中的队列处理
    laravel的模块化是如何实现的
  • 原文地址:https://www.cnblogs.com/lzh/p/822372.html
Copyright © 2020-2023  润新知