Finalize 和Dispose(bool disposing)和 Dispose() 的相同点:

这三者都是为了释放非托管资源服务的.

Finalize 和 Dispose() 和Dispose(bool disposing)的不同点:

  1. Finalize是CRL提供的一个机制, 它保证如果一个类实现了Finalize方法,那么当该类对象被垃圾回收时,垃圾回收器会调用Finalize方法.而该类的开发者就必须在Finalize方法中处理 非托管资源的释放. 但是什么时候会调用Finalize由垃圾回收器决定,该类对象的使用者(客户)无法控制.从而无法及时释放掉宝贵的非托管资源.由于非托管资源是比较宝贵了,所以这样会降低性能.
  2. Dispose(bool disposing)不是CRL提供的一个机制, 而仅仅是一个设计模式(作为一个IDisposable接口的方法),它的目的是让供类对象的使用者(客户)在使用完类对象后,可以及时手动调用非托管资源的释放,无需等到该类对象被垃圾回收那个时间点.这样类的开发者就只需把原先写在Finalize的释放非托管资源的代码,移植到Dispose(bool disposing)中.  而在Finalize中只要简单的调用 "Dispose(false)"(为什么传递false后面解释)就可以了.

这个时候我们可能比较疑惑,为什么还需要一个Dispose()方法?难道只有一个Dispose(bool disposing)或者只有一个Dispose()不可以吗? 
答案是:  
        只有一个Dispose()不可以. 为什么呢?因为如果只有一个Dispose()而没有Dispose(bool disposing)方法.那么在处理实现非托管资源释放的代码中无法判断该方法是客户调用的还是垃圾回收器通过Finalize调用的.无法实现 判断如果是客户手动调用,那么就不希望垃圾回收器再调用Finalize()(调用GC.SupperFinalize方法).另一个可能的原因(:我们知道如果是垃圾回收器通过Finalize调用的,那么在释放代码中我们可能还会引用其他一些托管对象,而此时这些托管对象可能已经被垃圾回收了, 这样会导致无法预知的执行结果(千万不要在Finalize中引用其他的托管对象).

所以确实需要一个bool disposing参数, 但是如果只有一个Dispose(bool disposing),那么对于客户来说,就有一个很滑稽要求,Dispose(false)已经被Finalize使用了,必须要求客户以Dispose(true)方式调用,但是谁又能保证客户不会以Dispose(false)方式调用呢?所以这里采用了一中设计模式:重载  把Dispose(bool disposing)实现为 protected, 而Dispose()实现为Public,那么这样就保证了客户只能调用Dispose()(内部调用Dispose(true)//说明是客户的直接调用),客户无法调用Dispose(bool disposing).

范例如下:

public class BaseResource: IDisposable 

  //析构函数自动生成 Finalize 方法和对基类的 Finalize 方法的调用.默认情况下,一个类是没有析构函数的,也就是说,对象被垃圾回收时不会被调用Finalize方法 
  ~BaseResource()      
   { 
      // 为了保持代码的可读性性和可维护性,千万不要在这里写释放非托管资源的代码 
      // 必须以Dispose(false)方式调用,以false告诉Dispose(bool disposing)函数是从垃圾回收器在调用Finalize时调用的 
      Dispose(false); 
   } 
   
   
   // 无法被客户直接调用 
   // 如果 disposing 是 true, 那么这个方法是被客户直接调用的,那么托管的,和非托管的资源都可以释放 
   // 如果 disposing 是 false, 那么函数是从垃圾回收器在调用Finalize时调用的,此时不应当引用其他托管对象所以,只能释放非托管资源 
   protected virtual void Dispose(bool disposing) 
   { 
      
         // 那么这个方法是被客户直接调用的,那么托管的,和非托管的资源都可以释放 
         if(disposing) 
         { 
            // 释放 托管资源 
            OtherManagedObject.Dispose(); 
         } 
         
         
         //释放非托管资源 
         DoUnManagedObjectDispose(); 
         
                 
         // 那么这个方法是被客户直接调用的,告诉垃圾回收器从Finalization队列中清除自己,从而阻止垃圾回收器调用Finalize方法.         
         if(disposing)  
           GC.SuppressFinalize(this);   
           
   }  
   
   //可以被客户直接调用 
   public void Dispose() 
   { 
     //必须以Dispose(true)方式调用,以true告诉Dispose(bool disposing)函数是被客户直接调用的 
      Dispose(true);      
   } 
}

上面的范例达到的目的:

1/ 如果客户没有调用Dispose(),未能及时释放托管和非托管资源,那么在垃圾回收时,还有机会执行Finalize(),释放非托管资源,但是造成了非托管资源的未及时释放的空闲浪费

2/ 如果客户调用了Dispose(),就能及时释放了托管和非托管资源,那么该对象被垃圾回收时,不回执行Finalize(),提高了非托管资源的使用效率并提升了系统性能

可以参考SqlConnection对象的New, Open, Close(内部调用Dispose())的使用经历可以加深对他们的理解.谢谢!

zz from zendy blog:http://www.cnblogs.com/caomao/archive/2005/05/10/152505.html

转载于:https://www.cnblogs.com/shawnliu/archive/2009/03/05/1403548.html

对.Net 垃圾回收的C#编程相关方面(Finalize 和Dispose(bool disposing)和 Dispose())的一些理解体会【个人复习+zz】...相关推荐

  1. 对.Net 垃圾回收的C#编程相关方面(Finalize 和Dispose(bool disposing)和 Dispose())的一些理解体会...

    Finalize 和Dispose(bool disposing)和 Dispose() 的相同点: 这三者都是为了释放非托管资源服务的. Finalize 和 Dispose() 和Dispose( ...

  2. .NET深入学习笔记(3):垃圾回收与内存管理

    今天抽空来讨论一下.Net的垃圾回收与内存管理机制,也算是完成上个<WCF分布式开发必备知识>系列后的一次休息吧.以前被别人面试的时候问过我GC工作原理的问题,我现在面试新人的时候偶尔也会 ...

  3. 深入了解C#系列:谈谈C#中垃圾回收与内存管理机制

    今天抽空来讨论一下.Net的垃圾回收与内存管理机制,也算是完成上个<WCF分布式开发必备知识>系列后的一次休息吧.以前被别人面试的时候问过我GC工作原理的问题,我现在面试新人的时候偶尔也会 ...

  4. C# 垃圾回收机制(转)

    摘要:今天我们漫谈C#中的垃圾回收机制,本文将从垃圾回收机制的原理讲起,希望对大家有所帮助. GC的前世与今生 虽然本文是以.NET作为目标来讲述GC,但是GC的概念并非才诞生不久.早在1958年,由 ...

  5. C#垃圾回收机制(GC)

    GC的前世与今生 虽然本文是以.net作为目标来讲述GC,但是GC的概念并非才诞生不久.早在1958年,由鼎鼎大名的图林奖得主John McCarthy所实现的Lisp语言就已经提供了GC的功能,这是 ...

  6. gc java root_C#技术漫谈之垃圾回收机制(GC)

    GC的前世与今生 虽然本文是以.NET作为目标来讲述GC,但是GC的概念并非才诞生不久.早在1958年,由鼎鼎大名的图林奖得主John McCarthy所实现的Lisp语言就已经提供了GC的功能,这是 ...

  7. C#垃圾回收机制GC

    本章主要讲解以下C#的垃圾回收机制,之前也有文章提到: Effect C# 学习笔记 .Net资源管理_dmk17771552304的博客-CSDN博客 为什么要使用GC 提高了软件开发的抽象度 程序 ...

  8. C#技术漫谈之垃圾回收机制(GC)

    虽然本文是以.NET作为目标来讲述GC,但是GC的概念并非才诞生不久.早在1958年,由鼎鼎大名的图林奖得主John McCarthy所实现的Lisp语言就已经提供了GC的功能,这是GC的第一次出现. ...

  9. C#垃圾回收学习总结

    浅谈C#垃圾回收 http://www.cnblogs.com/cuiyiming/archive/2013/03/26/2981931.html 理解C#垃圾回收机制我们首先说一下CLR(公共语言运 ...

  10. 学习笔记【Java 虚拟机②】垃圾回收

    若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 总目录 学习笔记[Java 虚拟机①]内存结构 学习笔记[Java 虚拟机②]垃圾回收 学习笔记[Java ...

最新文章

  1. python3.7.1安装教程详细_CentOS 7 安装python3.7.1的方法及注意事项
  2. IT管理人员需要更加了解数据中心冷却情况
  3. 在Action类中获得HttpServletResponse对象的四种方法
  4. mui实现分享功能_MUI 分享功能(微信、QQ 、朋友圈)
  5. 信息学奥赛一本通 1100:金币 | 1969:【15NOIP普及组】金币 | OpenJudge NOI 1.5 45 | 洛谷 P2669 [NOIP2015 普及组] 金币
  6. android 渐变展示启动屏
  7. linux中sudo命令_Linux中的Sudo命令
  8. 日常管理随笔一 (转载)
  9. React.js引入阿里icon解决icon显示为小方框问题
  10. 压摆率//电源抑制比//共模抑制比//直流增益、带宽和相位裕度//静态功耗和直流工作点
  11. 新注册第一帖----------------------乱码新手自学.net 之Linq 入门篇
  12. [ZZ] 为什么中国目前仍然没有一流的三维动画电影
  13. Windows系统中的睡眠时间和关闭屏幕时间的设置
  14. 移动端切图内容包括什么_移动终端界面切图
  15. 找出列表中最大或最小的元素-python3
  16. 16. 求两点之间的最短路径
  17. c语言double型小数点后几位小数,c语言double类型默认输出几位小数?
  18. JavaScript网页--跨年倒计时
  19. python生成简单名片二维码(不带图片)
  20. 鸿蒙系统应用开发初体验(一)

热门文章

  1. linux socket 阻塞服务端 非阻塞客户端,Linux socket非阻塞connect方法
  2. 應用程式中發生伺服器錯誤
  3. 源码剖析panic与recover,看不懂你打我好了!
  4. Json转XML后将首字母大写(或者其他自己的需求格式)对象中包含list集合以及日期字段的处理(注解形式)
  5. qpython3打开app_Android QPython3 扩展:调用其他App打开文件
  6. win10系统电脑修改注册表设置自动锁屏时间
  7. html oa 表单,OA表单制作(致远)
  8. 公众号推送长图最佳尺寸_微信公众平台图片尺寸是多少
  9. 光流法+FAST特征点
  10. linux比较两个文件的不同