从GC的SuppressFinalize方法带你深刻认识Finalize底层运行机制
如果你经常看开源项目的源码,你会发现很多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底层运行机制的更多相关文章
- Django 如何让ajax的POST方法带上CSRF令牌
问题 大家知道,在大前端领域,有一种叫做ajax的东东,即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),它被用来在不刷新页面的情况下,提 ...
- [整理] C#调用SQLDMO.DLL时间数据库备份 / 还原。 (香神无涯) // C#实现SQLSERVER2000数据库备份还原的两种方法 (带进度条)
/// <summary>/// 通过调用MSSQL的SQLDMO.DLL文件来实现备份数据库/// 1.首先在在项目中引用SQLDMO.DLL文件./// 2.在引用中的SQLDMO.D ...
- python中requests库get方法带参数请求
起因是想爬五等分的花嫁的漫画.这是其中的一个坑 先上代码 data={ 'cid':567464, , 'key':'', 'language':1, 'gtk':6, '_cid':567464, ...
- 发布Qt Quick桌面应用程序的方法(使得planets在XP上运行)
发布Qt Quick桌面应用程序的方法 Qt是一款优秀的跨平台开发框架,它可以在桌面.移动平台以及嵌入式平台上运行.目前Qt 5介绍程序发布的文章帖子比较少.大家又非常想要知道如何发布Qt应用程序,于 ...
- Java带包结构调用命令行运行编译
原文: https://www.toutiao.com/i6491809562037846542/ 带包结构调用命令行运行编译. 记事本编写两个简单的类 文件结构目录 启动DOS,进入文件所在目录 分 ...
- Delphi 在使用exports中的方法 带参数的用法
最近项目中,需要在一个bpl中调用另一个bpl中的单元的方法, 方法如下: 在被调用的单元中定义: procedure Inner_Ex(VoucherType: TVoucherType); exp ...
- java项目打包成可运行的jar,main方法带参数
转载 原文地址:http://www.cnblogs.com/neillee/p/6063808.html#commentform 将 java 项目打包成可运行的 jar 包(main 函数带参数) ...
- 深入理解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涉及术 ...
- 使用PHP生成二维码的两种方法(带logo图像)
一.利用Google API生成二维码 Google提供了较为完善的二维码生成接口,调用API接口很简单,以下是调用代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
随机推荐
- Blazor入门笔记(5)-数据绑定
1.环境 VS2019 16.5.1 .NET Core SDK 3.1.200 Blazor WebAssembly Templates 3.2.0-preview2.20160.5 2.默认绑定 ...
- Docker基础修炼1--Docker简介及快速入门体验
本文作为Docker基础系列第一篇文章,将详细阐述和分析三个问题:Docker是什么?为什么要用Docker?如何快速掌握Docker技术? 本系列文章中Docker的用法演示是基于CentOS7进行 ...
- rem布局和使用js rem动态改变字体大小,自适应
解决rem文字动态改变字体大小: <script> console.log(window.devicePixelRatio); var iScale = 1; iScale = iScal ...
- PTA数据结构与算法题目集(中文) 7-7
PTA数据结构与算法题目集(中文) 7-7 7-7 六度空间 (30 分) “六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论.这个理论可以通俗地阐述为 ...
- 安装elasticsearch-head(源码安装方式)
gitHub 地址 https://github.com/mobz/elasticsearch-head 克隆到本地 进行npm 安装运行 git clone git://github.com/mob ...
- EntityFramework Core 3.x上下文构造函数可以注入实例呢?
前言 今天讨论的话题来自一位微信好友遇到问题后请求我的帮助,当然他的意图并不是本文标题,只是我将其根本原因进行了一个概括,接下来我们一起来探索标题的问号最终的答案是怎样的呢? 上下文构造函数是否可以注 ...
- 家庭版记账本app开发进度。开发到现在整个app只剩下关于图表的设计了,具体功能如下
首先说一下自己的功能: 实现了用户的登录和注册.添加收入记账和添加支出记账.粗略显示每条账单基本情况.通过点击每条账单来显示具体的情况, 之后就是退出当前用户的操作. 具体的页面情况如下: 这就是整个 ...
- 列表的增加、修改、删除; list方法降序排序;练习注册
stus='xiaoming,xiaohei,xiaobai' #数组.列表.list,array stus = ['xiaoming','xiaohei','xiaobai' ] #列表# 0 1 ...
- ubuntu core文件
ubuntu开启core 检查是否开启core ulimit -c //0表示没有开启 开启core ulimit -c unlimited sudo sh -c 'echo 1 > /proc ...
- .NET 下基于动态代理的 AOP 框架实现揭秘
.NET 下基于动态代理的 AOP 框架实现揭秘 Intro 之前基于 Roslyn 实现了一个简单的条件解析引擎,想了解的可以看这篇文章 https://www.cnblogs.com/weihan ...