.net研究之垃圾回收

1.为什么要进行垃圾回收
  对于托管对象不再使用时,CLR会自动回收分配给对象的内存;而对于非托管资源,CLR将不会对其处理,所以要显式释放非托管资源。
2.析构函数, 终结器, Object.Finalize()
  终结器用于释放非托管资源。
  终结器是通过覆写Object类的Finalize()来定义的。
  对象被垃圾收集器收集时会调用终结器,当调用了GC.SuppressFinalize后,将不再调用对象的终结器(析构函数)。
  C#不能重写Object的Finalize()方法,析构函数代替Finalize()的实现
3.IDisposable接口
  当需要显式释放非托管资源时,可以实现IDisposable接口。
  实现IDisposable的Disposable方法,便于主动释放非托管资源。
  使用一个标志变量,防止在多次调用Disposable进行重复清理。
  在清理之前,先调用GC.SuppressFinalize,防止调用析构函数重复清理。
  在调用Disposable后,通过引发System.Object.DisposedException异常来阻止对象的其他方法调用。
4.实现IDisposable的一些规则
  1.创建一个protected virthual void Pispose(bool bDisposeManagedRes)方法.在Dispose()方法中调用该方法并让
    bDisposeManagedRes参数为true;而在终结器中调用这个方法并让bDisposeManagedRes为false.
  2.在Dispose(bool bDisposeManagedRes)方法中释放所有的非托管资源,而仅当bDisposeManagedRes参数为true时释
    放托管资源.(注意,调用对象的Close()方法和Dispose()方法属于释放托管资源).
  3.在Dispose()方法中,调用Dispose(bool bDisposeManagedRes)重载方法之后调用GC.SuppressFinalize(this).这样
    就可以通知垃圾收集器不必再调用该对象的终结器.
5.using
  在使用了实现IDisposable的类时,必须在finally块中调用Dispose()方法,避免发生异常而跳过Dispose的调用.
  .Net中提供了另一种方式,可以利用using对Dispose自动调用,即使发生异常也会调用。
  例如:
       using (Font font3 = new Font("Arial", 10.0f), font4 = new Font("Arial", 10.0f))
       {
       // Use font3 and font4.
       }
       using里面有两个对象,在using块执行完毕时,会先调用font4的Dispose,然后再调用font3的
6.何时需要终结器和实现Dispose()
  任何包含一处或多处非托管资源的类(比如Windows对象的句柄)必须定义终结器来释放这些资源。
7.示例
  public class Foo:System.IDispose{
   public Foo()
   {
  
   }
   private bool bDisposed = false; //是否已经释放了资源
   public void Fct()
   {
     if(bDisposed)
       throw new System.ObjectDisposedException("Name of the object"); //在释放资源后,产生异常,避免方法再被调用
   }
   public void Dispose()
   {
     Dispose(true);
     System.GC.SuppressFinalize(this);
   }
   ~Foo(){Dispose(false);}
   protected virtual void Dispose(bool bDisposeManagedRes)
   {
     if(!bDisposed)
     {
       bDisposed = true;
       //释放非托管资源
       if(bDisposeManagedRes)
       {
         //释放托管资源
       }
     }
   }
  }

 

参考资料:
  MSDN, C#和.NET2.0实战, C#图解教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值