C#中IDisposable的用法-垃圾回收
在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机。对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收。那么什么时候使用Idisposable接口,以及如何使用呢?
一、IDisposable的接口定义如下
public interface IDisposable
{
// Summary:
// Performs application-defined tasks associated with freeing, releasing, or
// resetting unmanaged resources.
void Dispose();
}
二:IDisposable基本应用
1.定义一个实现了IDisposable接口的类


public class CaryClass :IDisposable
{
public void DoSomething()
{
Console.WriteLine("Do some thing....");
}
public void Dispose()
{
Console.WriteLine("及时释放资源");
}
}
2、两种方式来调用
(1)、使用Using语句会自动调用Dispose方法
using (CaryClass caryClass = new CaryClass())
{
caryClass.DoSomething();
}
(2)、现实调用该接口的Dispose方法
CaryClass caryClass = new CaryClass();
try
{
caryClass.DoSomething();
}
finally
{
IDisposable disposable = caryClass as IDisposable;
if (disposable != null)
disposable.Dispose();
}
三、IDisposable实现释放资源


public class DisposablClass : IDisposable
{
//是否回收完毕
bool _disposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
DisposableClass()
{
Dispose(false);
}
//这里的参数表示示是否需要释放那些实现IDisposable接口的托管对象
protected virtual void Dispose(bool disposing)
{
if(_disposed) return; //如果已经被回收,就中断执行
if(disposing)
{
//TODO:释放那些实现IDisposable接口的托管对象
}
//TODO:释放非托管资源,设置对象为null
_disposed = true;
}
}
四、IDisposable实例分析
Dispose()方法
当需要回收非托管资源的DisposableClass类,就调用Dispoase()方法。而这个方法不会被CLR自动调用,需要手动调用。
DisposableClass(),析构函数
当托管堆上的对象没有被其它对象引用,GC会在回收对象之前,调用对象的析构函数。这里的~DisposableClass()析构函数的意义在于告诉GC你可以回收我,Dispose(false)表示在GC回收的时候,就不需要手动回收了。
虚方法Dispose(bool disposing)
1、通过此方法,所有的托管和非托管资源都能被回收。参数disposing表示是否需要释放那些实现IDisposable接口的托管对象。
2、如果disposings设置为true,就表示DisposablClass类依赖某些实现了IDisposable接口的托管对象,可以通过这里的Dispose(bool disposing)方法调用这些托管对象的Dispose()方法进行回收。
3、如果disposings设置为false,就表示DisposableClass类依赖某些没有实现IDisposable的非托管资源,那就把这些非托管资源对象设置为null,等待GC调用DisposableClass类的析构函数,把这些非托管资源进行回收。
4、另外,以上把Dispose(bool disposing)方法设置为protected virtual的原因是希望有子类可以一起参与到垃圾回收逻辑的设计,而且还不会影响到基类。
比如有这样的一个子类


public class SubDisposableClass : DiposableClass
{
private bool _disposed; //表示是否已经被回收
protected override void Dispose(bool disposing)
{
if(!_disposed) //如果还没有被回收
{
if(disposiing) //如果需要回收一些托管资源
{
//TODO:回收托管资源,调用IDisposable的Dispose()方法就可以
}
//TODO:回收非托管资源,把之设置为null,等待CLR调用析构函数的时候回收
_disposed = true;
}
base.Dispose(disposing);//再调用父类的垃圾回收逻辑
}
}
五、IDisposable总结
当我们自定义的类及其业务逻辑中引用某些托管和非托管资源,就需要实现IDisposable接口,实现对这些资源对象的垃圾回收。
转载自 http://www.studyofnet.com/news/590.html
C#中IDisposable的用法-垃圾回收的更多相关文章
- C#中IDisposable的用法
在Net中,由GC垃圾回收线程掌握对象资源的释放,程序员无法掌控析构函数的调用时机.对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Id ...
- Java中内存泄露及垃圾回收机制
转自:http://blog.sina.com.cn/s/blog_538b279a0100098d.html 写的相当不错滴...................... 摘 要 Java语言中,内 ...
- Java中的分代垃圾回收策略
一.分代GC的理论基础 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大 ...
- 【Python】Python中对象管理与垃圾回收中两个很有意思的问题
再Python中是利用引用计数来实现对象管理和垃圾回收的,即其他对象引用该对象时候,其引用计数加1,反之减1,当引用计数为0时候,被垃圾收集器回收. Python解释器对对象以及计数器的管理分为以下两 ...
- Java中的构造器与垃圾回收
构造器 在我们初始化对象时,如果希望设置一些默认值,那么就可以使用构造器,在Java中,构造器使用和类同名的名字且没有返回值,如下 class Test{ private String name; T ...
- python中del函数的垃圾回收
今天学习面向对象里的类被del函数的垃圾回收过程搞的晕头转向,经过了老师的讲解还是是懂非懂,然后看了很多博客慢慢的心里才有了个大概的了解. 刚刚看到一篇博客,觉得讲的很好,转载过来以供参考.以下转自笨 ...
- [转] javascript中的变量和垃圾回收
[From] http://www.imooc.com/article/4585 基本类型和引用类型 js中的变量虽然不区分类型,但是实际上Ecmascript包含两种类型,基本类型和引用类型. 基本 ...
- 局部变量表中Slot复用对垃圾回收的影响详解
看两段代码 1. package com.jvm; public class Test { public static void main(String[] args) { { byte[] plac ...
- 图解JVM在内存中申请对象及垃圾回收流程
http://longdick.iteye.com/blog/468368 先看一下JVM的内存模型: 从大的方面来讲,JVM的内存模型分为两大块: 永久区内存( Permanent space )和 ...
随机推荐
- 获取url参数并且中文不乱码的方法
function getUrlArgument(name) { var reg = new RegExp("(^|&)" + name + "=([^&] ...
- 使用bat文件实现批量重命名功能
在生活中我们总会碰到对大量文件进行重命名操作,这时如果一个一个的,选取文件→右键→重命名→选取文件,这样操作势必会浪费大量时间. 现在小编就告诉大家一个使用bat文件(命令行)的方法,快速对文件进行重 ...
- untra edit 显示文件函数列表
UltraEdit的函数列表竟然不显示函数,那这功能要它何用,应该如何才能让函数显示出来呢? 1:先查看一下UE的菜单:视图-->查看方式(语法高亮类型)-->选择相应的语言(我们用的是C ...
- 蓝桥杯 算法训练 ALGO-141 P1102
算法训练 P1102 时间限制:1.0s 内存限制:256.0MB 定义一个学生结构体类型student,包括4个字段,姓名.性别.年龄和成绩.然后在主函数中定义一个结构体数组(长度不超过10 ...
- PAT L3-008. 喊山(BFS)C4 初赛30分
喊山(30 分) 喊山,是人双手围在嘴边成喇叭状,对着远方高山发出“喂—喂喂—喂喂喂……”的呼唤.呼唤声通过空气的传递,回荡于深谷之间,传送到人们耳中,发出约定俗成的“讯号”,达到声讯传递交流的目的. ...
- Excel开发学习笔记:发布VSTO下的Excel开发项目
遇到一个数据处理自动化的问题,于是打算开发一个基于excel的小工具.在业余时间一边自学一边实践,抽空把一些知识写下来以备今后参考,因为走的是盲人摸象的野路子,幼稚与错误请多包涵. 开发环境基于VST ...
- CreateMutex实现只能打开一个客户端
#include "stdafx.h" #include <Windows.h> #include <iostream> using namespace s ...
- hadoop报错java.io.IOException: Incorrect configuration: namenode address dfs.namenode.servicerpc-address or dfs.namenode.rpc-address is not configured
不多说,直接上干货! 问题详情 问题排查 spark@master:~/app/hadoop$ sbin/start-all.sh This script is Deprecated. Instead ...
- java之控制多幅图片
package xxj.thread0904; import java.awt.Image; import javax.swing.ImageIcon; import javax.swing.JFra ...
- 『原』在Linux下反编译Android .apk文件 使用apktool dex2jar JD-eclipse
一.使用apktool 将 apk反编译生成程序的源代码和图片.XML配置.语言资源等文件 具体步骤: (1)下载反编译工具包:apktool 官方的打不开 http://apktool.shouji ...