资源释放的问题

个人体悟,析构貌似有点鸡肋了,不能显示调用,不也确定调用时机,应该只是做为一种释放资源机制的存在

然后,一个实例类的资源释放应在承载它的方法结束时发生,所以做为主程序结束标志的main函数里才不能写一些冗杂的方法在里面,应把方法写在主程序外面,要用的时候调用一下这样可以省资源、而且有复用性。不知道我这样理解是否有问题。若有不对之处,还请指点,入门新人!

C#中Dispose、析构函数、close的区别

本文导读:C#中析构函数 和 Dispose 都是释放资源,析构函数用于 隐式释放资源,Dispose用于 显式释放资源,也就是析构函数 是对象不可访问后自动被调用的,Dispose 是类使用者调用的;close方法表示关闭资源,并不一定代表会释放资源。

析构函数不能显示调用,而对于Dispose、close方法来说,都需要进行显示调用才能被执行。

一、Close与Dispose这两种方法的区别

调用完了对象的Close方法后,此对象有可能被重新进行使用;而Dispose方法来说,此对象所占有的资源需要被标记为无用了,也就是此对象要被销毁,不能再被使用。例如常见.Net类库中的SqlConnection这个类,当调用完Close方法后,可以通过Open重新打开一个数据库连接,当彻底不用这个对象了就可以调用Dispose方法来标记此对象无用,等待GC回收。

二、三者的区别如图

 
析构函数


Dispose方法

Close方法
意义 销毁对象 销毁对象 关闭对象资源
调用方式 不能被显示调用,在GC回收是被调用
需要显示调用或者通过using语句
需要显示调用
调用时机 不确定 确定,在显示调用或者离开using程序块 确定,在显示调用时

三、析构函数 和 Dispose 的说明

1. Dispose需要实现IDisposable接口。

2. Dispose由开发人员代码调用,而析构函数由GC自动调用。

3. Dispose方法应释放所有托管和非托管资源。而析构函数只应释放非托管资源。因为析构函数由GC来判断调用,当GC判断某个对象不再需要的时候,则调用其析构方法,这时候该对象中可能还包含有其他有用的托管资源。

4. 通过系统GC频繁的调用析构方法来释放资源会降低系统性能,所以推荐显示调用Dispose方法。

5. Dispose方法结尾处加上代码“GC.SuppressFinalize(this);”,即告诉GC不需要再调用该对象的析构方法,否则,GC仍会在判断该对象不再有用后调用其析构方法,虽然程序不会出错,但影响系统性能。

6、析构函数 和 Dispose 释放的资源应该相同,这样即使类使用者在没有调用 Dispose 的情况下,资源也会在 Finalize 中得到释放。

7、Finalize 不应为 public。

8、有 Dispose 方法存在时,应该调用它,因为 Finalize 释放资源通常是很慢的。

四、Close函数的说明

Close 这个方法在不同的类中有不同的含义,并没有任何规定要求 Close 具有特殊的含义,也就是说 Close 并不一定要释放资源,您也可以让 Close 方法表示“关门”。

不过,由于 Close 有“关”的意思,通常也把 Close 拿来释放资源,这也是允许的。比如文件操作中,用 Close 释放对象似乎比 Dispose 含义更准确,于是在设计类时,可以将 Close 设为 public,将 Dispose 设为 protected,然后由 Close 调用 Dispose。

也就是说 Close 表示什么意思,它会不会释放资源,完全由类设计者决定。网上说“Close 调用 Dispose”这种方法是很片面的。在 SqlConnection 中 Close 只是表示关闭数据库连接,并没有释放 SqlConnection 这个对象资源。

根据经验,Close 和 Dispose 同时存在的情况下(均为 public),Close 并不表示释放资源,因为通常情况下,类设计者不应该使用两个 public 方法来释放相同的资源。

五、析构函数和Dispose方法实例

C# 代码   复制

public class BaseResource: IDisposable

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

资源释放的问题的相关文章

opencv资源释放问题

初学opencv,资源释放问题困扰了好久.感觉小有体会,仅供菜鸟参考. 资源要不要释放主要看是否真正在内存开辟空间.简单点说就是有Creat开辟空间,才有Release的释放空间.当然实际情况要更复杂,比如clone()等深复制.总之还是要看是否真正在内存开辟空间. 具体的参考一下以下3篇文章吧 http://blog.csdn.net/scudz/article/details/8083866 http://blog.csdn.net/liulina603/article/details/84

泛型的资源释放

C#泛型是一种高复用性.安全和高效的技术,通过类型参数可以将参数的声明.实现推迟到客户代码中.但是这种延迟却降低了类型参数在泛型定义中的可操作性.例如资源释放. public interface IWorker { void Operate(); } public class GenericWorker<T> where T : IWorker , new() { public void GetResult() { T worker=new T(); worker.Operate(); } }

深刻理解C#中资源释放

今天我的一个朋友看到我写的那篇<C#中用AJAX验证用户登录>时,给我指出了点小毛 病.就是在用户登录时,如果用户登录失败,在下面这段代码中,都会new出来一个User对象,如果连续登录失败多次,就会生成多个User对象,而它们 在登录失败后已经无用了,依然占据着内存,就算是C#有垃圾回收机制,但不确定什么时候对这些对象进行回收.然后去网上找了一篇C#资源释放的文章,讲的很透彻,和大家分享一下. using System;using System.Collections.Generic;usi

cocos2dx loading界面 预加载资源 与 资源释放

预加载图片: 1.CCTextureCache::sharedTextureCache()->addImage("icon.png"); 2.CCTextureCache::sharedTextureCache()->addImageAsync("icon.png",this,callfuncO_selector(MainLayerLoading::loadingCallBack)); 使用加载的缓存图片: CCSprite* sp =CCSprite:

.net 资源释放(托管资源和非托管资源)

1.托管资源 像int.float.DateTime等都是托管资源:net中80%的资源都是托管资源: 托管资源的回收通过GC(垃圾回收器)自动释放分配给该对象的内存,但无法预测进行垃圾回收的时间,我们无法控制系统在什么时间回收资源. 2.非托管资源 像ApplicationContext,Brush,Component,ComponentDesigner,Container,Context,Cursor,FileStream,Font,Icon,Image,Matrix,Object,Odbc

C#资源释放及Dispose、Close和析构方法

备注:此文的部分观点有误,之所以仍旧保留本文,是需要在后期给出一个勘误版.正确的版本在这里“C#中标准Dispose模式的实现” 一:什么是资源 在开始本文前,需要一些准备知识.首先要提出“什么是资源”.在CLR出来之后,Windows系统资源开始分为“非托管资源”和“托管资源”. 非托管资源是指:所有的Window内核对象(句柄)都是非托管资源,如对于Stream,数据库连接,GDI+的相关对象,还有Com对象等等,这些资源并不是受到CLR管理: 托管资源是指:由CLR管理分配和释放的资源,即

oracle for update锁表资源释放之kill -9和alter system kill session &#39;sid,serial#&#39;;

通过for update锁表,通过操作系统方式和oracle方式终止进程方式 --查询需要终止进程的情况,包括操作系统进程 select proc.sPID, sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo.locked_mode from v$locked_object lo, dba_objects ao, v$session sess,v$process proc where a

JDBC的资源释放

1.1.1?JDBC资源释放 JDBC程序执行结束后,将与数据库进行交互的对象释放掉,通常是ResultSet,Statement,Connection. 这几个对象中尤其是Connection对象是非常稀有的.这个对象一定要做到尽量晚创建,尽早释放掉. l 将资源释放的代码写入到finally的代码块中. l 资源释放的代码应该写的标准: if(rs !=null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(

数据库连接资源释放

项目运行过程中遇到了tomcat连接池资源不释放,导致系统崩溃的问题. 查找各种网站,在数据库中进行如下配置 (tomcat): 1.initialSize :连接池启动时创建的初始化连接数量 2.maxActive :连接池中可同时连接的最大的连接数 3.maxIdle:连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制 4.minIdle:连接池中最小的空闲的连接数,低于这个数量会被创建新的连接 5.maxWait  :最大等待时间,当没有可用连接时,连接池等待连接