C# Dispose模式详细分析
C#Dispose模式
- 目的:
为了及时释放宝贵的非托管资源和托管资源,并且保证资源在被gc回收的时候可以正确释放资源,同时兼顾执行效率
- 必须遵循的事实:
1 托管资源释放:
由另一线程的gc进行释放,当托管的对象没有被引用时,就会在“适当的时候”进行回收
如果定义了析构函数,回收的时候会调用析构函数(实际执行可能有差别),之后释放对象占用的内存。
当类有析构函数时, gc会分分两步来释放,如果没有析构函数或者指定不需要调用析构函数时,只需要一步就能释放
2 非托管资源必须显式释放
- 方案:
1.把资源释放都放在析构函数里。
可以保证资源都释放,但是由于gc调用时机的不确定性,导致宝贵的非托管资源无法及时释放。
2. 写个释放函数,手动是调用
如果忘了释放的话, 托管资源会被gc释放,但非托管资源就无法释放
3. Dispose模式。参考下面的代码
手动调用Dispose() 可以释放所有资源,并且在gc标记不需要再调用析构函数,从而提高了效率。
如果忘记调用Dispose(), 则当gc调用析构函数的时候也会把非托管资源释放掉
-------参考代码-----------
public interface IDisposable
{
void Dispose();
}
public class DisposablClass : IDisposable
{
//是否回收完毕
bool _disposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this); //标记gc不在调用析构函数
}
~DisposableClass()
{
Dispose(false);
} private void Dispose(bool disposing)
{
if(_disposed) return; //如果已经被回收,就中断执行
if(disposing)
{
//TODO:释放本对象中管理的托管资源
}
//TODO:释放非托管资源
_disposed = true;
}
}
- 可能存在的疑问
1. 既然gc是另外一线程执行的,为什么Dispose(bool)函数里不加锁?
答:因为如果可以主动调用的时候,肯定此对象不是死对象,也不会被回收,因此不会同时调用到
2. 为什么析构函数调用的dispose(false)不释放托管资源?
答:因为析构函数由gc来调用,gc会依次释放所有的死对象(不可到达),释放的顺序是随机的,如果在一个对象的析构里调用了一个本次gc已经释放的对象,就会发生释放两次的错误。
- 这个讲的也不错,就是有点啰嗦:
https://blog.csdn.net/zrf2112/article/details/50644652
C# Dispose模式详细分析的更多相关文章
- 基于Java 生产者消费者模式(详细分析)
Java 生产者消费者模式详细分析 本文目录:1.等待.唤醒机制的原理2.Lock和Condition3.单生产者单消费者模式4.使用Lock和Condition实现单生产单消费模式5.多生产多消费模 ...
- Java 生产者消费者模式详细分析
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- activity的四种启动模式详细分析
1.android中通过任务队列来管理activity 采用栈的结构就是后进先出 手机里面如果启动多个应用就会启动多个任务栈来管理对应的activity. 主要解决下面的问题:对应的四种启动模式: 1 ...
- Android-Native-Server 启动和注册详细分析
Android-Native-Server 启动和注册详细分析 以mediaService为实例来讲解: mediaService的启动入口 是一个 传统的 main()函数 源码位置E:\ ...
- Http Pipeline详细分析(下)
Http Pipeline详细分析(下) 文章内容 接上面的章节,我们这篇要讲解的是Pipeline是执行的各种事件,我们知道,在自定义的HttpModule的Init方法里,我们可以添加自己的事件, ...
- /etc/rc.d/init.d/functions文件详细分析
/etc/rc.d/init.d/functions文件详细分析 functions这个脚本是给/etc/init.d里边的文件使用的(可理解为全局文件). 提供了一些基础的功能,看看里边究竟有些什么 ...
- 微软和Google的盈利模式对比分析
一: 微软和Google是世界上最成功科技巨头之一,但他们之间却有着不同的产品和业务,二者的盈利方式也各有不同,本文将分析和探讨的二者盈利模式的异同. 微软的盈利模式 在1975年由大学肄业的Bill ...
- IDea 工具debug模式详细使用说明
IDea 工具debug模式详细使用说明 IDEA中如何使用debug调试项目 一步一步详细教程 Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生 ...
- 13万字详细分析JDK中Stream的实现原理
前提 Stream是JDK1.8中首次引入的,距今已经过去了接近8年时间(JDK1.8正式版是2013年底发布的).Stream的引入一方面极大地简化了某些开发场景,另一方面也可能降低了编码的可读性( ...
随机推荐
- Chipmunk僵尸物理对象的出现和解决(六)
既然出现了这个问题下面就是如何找到原因. 因为该问题不是每次都出现,偶尔反弹棒碰到五角星时才会多出一个僵尸棒,现象比较随机,较难悉知具体原因. 有时多次触碰又没有出现问题,有时短时间内每次触碰都出现问 ...
- linux(centos)下mysql忘记root密码
1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库. 重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的 状态下,其他的用户也可以任意地登录和修 ...
- 制药企业BI系统方案整体设计分享
制药企业全面预算系统蓝图 全面掌控企业的各种业务活动,及时准确的展现它们的状况与趋势,评估其达成的效果.存在的问题与风险.支持数据的导入,多级上报等多种特色功能,同时通过统一的报表平台实现精细话的权限 ...
- unity 球体表面平均分割点
之前看了别人的一份源码,讲到了球体表面平均分割点,于是也好奇去查了一下算法,自己写不出来,借用算法在unity写了一个小demo using UnityEngine; using System.Col ...
- apktool动态破解apk
那么今天我们就用另外一种方式来破解apk:动态方式,关于动态方式其实很广义的,因为动态方式相对于静态方式来说,难度大一点,但是他比静态方式高效点,能够针对更过的破解范围.当然动态方式很多,所以这里就分 ...
- Spring--ClassPathResource
/* * 用一个给定的类加载器或者给定的类来加载资源 */ public class ClassPathResource extends AbstractFileResolvingResource { ...
- 最新App Store审核10大被拒理由
最近,苹果在官网给出了截至2015年2月份应用被拒绝的十大理由,其中50%以上的应用被拒绝都是因为这10个原因,其中7个理由和2014年相同,其中排名前三的原因分别是:需要补充更多信息.存在明显的bu ...
- C++语言之类class
在现实世界中,经常有属于同一类的对象.例如,你的自行车只是世界上很多自行车中的一辆.在面向对象软件中,也有很多共享相同特征的不同的对象:矩形.雇用记录.视频剪辑等.可以利用这些对象的相同特征为它们建立 ...
- Spring 官网下载zip jar
第一步:打开官网:http://www.springsource.org/download/community: 第二步:点击图片 第三步:点击图标 第四步:找到如下链接,点击进去 第五步:再找到如下 ...
- 采用UltraISO制作U盘启动盘
采用UltraISO制作U盘启动盘 打开UltralSO,选择"文件"--->"打开",如下图: 图1 打开WIN7操作系统的ISO文件,如下图: 图2 ...