如果你经常看开源项目的源码,你会发现很多Dispose方法中都有这么一句代码: GC.SuppressFinalize(this); ,看过一两次可能无所谓,看多了就来了兴趣,这篇就跟大家聊一聊。

一:背景

1. 在哪发现的

相信现在Mysql在.Net领域中铺的面越来越广了,C#对接MySql的MySql.Data类库的代码大家可以研究研究,几乎所有操作数据库的几大对象:MySqlConnection,MySqlCommand,MySqlDataReader以及内部的Driver都存在 GC.SuppressFinalize(this)代码。


public sealed class MySqlConnection : DbConnection, ICloneable
{
public new void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
} public sealed class MySqlCommand : DbCommand, IDisposable, ICloneable
{
public new void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}

2. GC.SuppressFinalize 场景在哪里

先看一下官方对这个方法的解释,如下所示:

        //
// Summary:
// Requests that the common language runtime not call the finalizer for the specified
// object.
//
// Parameters:
// obj:
// The object whose finalizer must not be executed.
//
// Exceptions:
// T:System.ArgumentNullException:
// obj is null.
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SecuritySafeCritical]
public static void SuppressFinalize(object obj);

意思就是说: 请求 CLR 不要调用指定对象的终结器,如果你对终结器的前置基础知识不足,那这句话肯定不是很明白,既然都执行了Dispose,说明非托管资源都被释放了,怎么还压制CLR不要调用Finalize呢?删掉和不删掉这句代码有没有什么严重的后果,GC类的方法谁也不敢动哈。。。 为了彻底讲清楚,有必要说一下Finalize整个原理。

二:资源管理

我们都知道C#是一门托管语言,它的好处就是不需要程序员去关心内存的分配和释放,由CLR统一管理,这样编程门槛大大降低,天下攘攘皆为利来,速成系的程序员就越来越多~

1. 对托管资源和非托管资源理解

<1> 托管资源

这个很好理解,你在C#中使用的值类型,引用类型都是统一受CLR分配和GC清理。

<2> 非托管资源

在实际业务开发中,我们的代码不可能不与外界资源打交道,比如说文件系统,外部网站,数据库等等,就拿写入文件的StreamWriter举例,如下代码:

        public static void Main(string[] args)
{
StreamWriter sw = new StreamWriter("xxx.txt");
sw.WriteLine("....");
}

为什么能够写入文件? 那是因为我们的代码是请求windows底层的Win32 Api帮忙写入的,这就有意思了,因为这个场景有第三者介入,sw是引用类型受CLR管理,win32 api属于外部资源和.Net一点关系都没有,如果你在用完sw之后没有调用close方法的话,当某个时候GC回收了托管堆上的sw后,这给被打开的win32 api文件句柄再也没有人可以释放了,资源就泄露了,如果没看懂,我画张图:

三:头疼的非托管资源解决方案

1. 使用析构函数

很多时候程序员就是在使用完类之后因为种种原因忘记了手动执行Close方法造成了资源泄露,那有没有一种机制可以在GC回收堆对象的时候回调我的一个自定义方法呢?如果能实现就

从GC的SuppressFinalize方法带你深刻认识Finalize底层运行机制的更多相关文章

  1. Django 如何让ajax的POST方法带上CSRF令牌

    问题 大家知道,在大前端领域,有一种叫做ajax的东东,即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),它被用来在不刷新页面的情况下,提 ...

  2. [整理] C#调用SQLDMO.DLL时间数据库备份 / 还原。 (香神无涯) // C#实现SQLSERVER2000数据库备份还原的两种方法 (带进度条)

    /// <summary>/// 通过调用MSSQL的SQLDMO.DLL文件来实现备份数据库/// 1.首先在在项目中引用SQLDMO.DLL文件./// 2.在引用中的SQLDMO.D ...

  3. python中requests库get方法带参数请求

    起因是想爬五等分的花嫁的漫画.这是其中的一个坑 先上代码 data={ 'cid':567464, , 'key':'', 'language':1, 'gtk':6, '_cid':567464, ...

  4. 发布Qt Quick桌面应用程序的方法(使得planets在XP上运行)

    发布Qt Quick桌面应用程序的方法 Qt是一款优秀的跨平台开发框架,它可以在桌面.移动平台以及嵌入式平台上运行.目前Qt 5介绍程序发布的文章帖子比较少.大家又非常想要知道如何发布Qt应用程序,于 ...

  5. Java带包结构调用命令行运行编译

    原文: https://www.toutiao.com/i6491809562037846542/ 带包结构调用命令行运行编译. 记事本编写两个简单的类 文件结构目录 启动DOS,进入文件所在目录 分 ...

  6. Delphi 在使用exports中的方法 带参数的用法

    最近项目中,需要在一个bpl中调用另一个bpl中的单元的方法, 方法如下: 在被调用的单元中定义: procedure Inner_Ex(VoucherType: TVoucherType); exp ...

  7. java项目打包成可运行的jar,main方法带参数

    转载 原文地址:http://www.cnblogs.com/neillee/p/6063808.html#commentform 将 java 项目打包成可运行的 jar 包(main 函数带参数) ...

  8. 深入理解JVM+G1+GC.pdf (中文版带书签)

    目录 序 VII前言 IX 第1章 JVM & GC基础知识 11.1 引言 21.2 基本术语 31.2.1 Java相关术语 41.2.2 JVM/GC通用术语 241.2.3 G1涉及术 ...

  9. 使用PHP生成二维码的两种方法(带logo图像)

    一.利用Google API生成二维码 Google提供了较为完善的二维码生成接口,调用API接口很简单,以下是调用代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...

随机推荐

  1. 【Python3爬虫】反反爬之破解同程旅游加密参数 antitoken

    一.前言简介 在现在各个网站使用的反爬措施中,使用 JavaScript 加密算是很常用的了,通常会使用 JavaScript 加密某个参数,例如 token 或者 sign.在这次的例子中,就采取了 ...

  2. 201771010108韩腊梅《面向对象程序设计(java)》第一周学习总结

    第一部分:课程准备部分 填写课程学习 平台注册账号, 平台名称 注册账号 博客园:www.cnblogs.com 木子林 程序设计评测:https://pintia.cn/ 19362039991@q ...

  3. 简单记录下RestTemplate 中postForObject调用例子

    学无止境! 今天无意中做了下RestTemplate调用demo,简单的尝试了下一个项目调用另一个项目接口示例 在A项目中创建可访问controller 然后在B项目中进行调用 调用成功

  4. 为什么MySQL要用B+树?聊聊B+树与硬盘的前世今生【宇哥带你玩转MySQL 索引篇(二)】

    为什么MySQL要用B+树?聊聊B+树与硬盘的前世今生 在上一节,我们聊到数据库为了让我们的查询加速,通过索引方式对数据进行冗余并排序,这样我们在使用时就可以在排好序的数据里进行快速的二分查找,使得查 ...

  5. Git常用命令(一)

    $ git init 初始化仓库(会生成一个隐藏文件.git) $ git add + (文件名) 实现对指定文件的跟踪 $ git commit 提交更新$ git clone + URL 克隆远程 ...

  6. python3(二十七)property

    """ """ __author__ = 'shaozhiqi' # 绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单, # 但是, ...

  7. CentOS Linux安装后扩充SWAP分区

    1. 首先先查看目前swap分区大小:     free -hm    total used free shared buffers cached    Mem: 11G 801M 10G 236K ...

  8. 《JavaScript 模式》读书笔记(6)— 代码复用模式2

    上一篇讲了最简单的代码复用模式,也是最基础的,我们普遍知道的继承模式,但是这种继承模式却有不少缺点,我们下面再看看其它可以实现继承的模式. 四.类式继承模式#2——借用构造函数 本模式解决了从子构造函 ...

  9. CSS躬行记(6)——滤镜

    滤镜(filter)可改造元素的视觉呈现,CSS内置的滤镜有10种,通过SVG文件还能自定义滤镜. 一.调色滤镜 调色滤镜可控制元素的模糊.颜色.亮度等变化,并且多个滤镜可组合在一起使用.这些滤镜大部 ...

  10. 如何用python无账号无限制获取企查查信息

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取http ...