当前位置:  编程技术>.net/c#/asp.net

浅谈关于C#的垃圾回收机制

    来源: 互联网  发布时间:2014-10-18

    本文导语:    理解C#垃圾回收机制我们首先说一下CLR(公共语言运行时,Common Language Runtime)它和Java虚拟机一样是一个运行时环境,核心功能包括:内存管理、程序集加载、安全性、异步处理和线程同步。 CTS(Common Type System)通用类型系...

  理解C#垃圾回收机制我们首先说一下CLR(公共语言运行时,Common Language Runtime)它和Java虚拟机一样是一个运行时环境,核心功能包括:内存管理、程序集加载、安全性、异步处理和线程同步。

CTS(Common Type System)通用类型系统,它把.Net中的类型分为2大类,引用类型与值类型。.Net中所有类型都间接或直接派生至System.Object类型。所有的值类型都是System.ValueType的子类,而System.ValueType本身却是引用类型。


托管资源:
  由CLR管理的存在于托管堆上的称为托管资源,注意这里有2个关键点,第一是由CLR管理,第二存在于托管堆上。托管资源的回收工作是不需要人工干预的,CLR会在合适的时候调用GC(垃圾回收器)进行回收。

非托管资源:
  非托管资源是不由CLR管理,例如:Image Socket, StreamWriter, Timer, Tooltip, 文件句柄, GDI资源, 数据库连接等等资源(这里仅仅列举出几个常用的)。这些资源GC是不会自动回收的,需要手动释放。


通过上面的讲述总结一下,第一,GC(垃圾回收器)只回收托管资源,不回收非托管资源。第二,GC回收是要在合适的时候(CLR觉得应该进行回收的时候)才进行回收。那么非托管如何进行回收呢?下面就让我一一道来。

在.Net中释放非托管资源主要有2种方式,Dispose,Finalize

Dispose方法,对象要继承IDisposable接口,也就会自动调用Dispose方法。

代码如下:

Class Suifeng:System.IDisposable
{
    #region IDisposable 成员

     public void Dispose()
     {
         //
     }

     #endregion
}

Suifeng suiFeng= new Suifeng ();

suiFeng.Dispose();

//也可以使用Using语句
(using Suifeng suiFeng= new Suifeng())
{
     //
}

Finalize()方法

MSDN上的定义是允许对象在“垃圾回收”回收之前尝试释放资源并执行其他清理操作。
它的本质就是析构函数

代码如下:

class Car
{
    ~Car()  // destructor
    {
        // cleanup statements...
    }
}

该析构函数隐式地对对象的基类调用 Finalize。 这样,前面的析构函数代码被隐式地转换为以下代码:

代码如下:

protected override void Finalize()
{
    try
    {
        // Cleanup statements...
    }
    finally
    {
        base.Finalize();
    }
}

在.NET中应该尽可能的少用析构函数释放资源,MSDN2上有这样一段话:
  实现 Finalize 方法或析构函数对性能可能会有负面影响,因此应避免不必要地使用它们。用 Finalize 方法回收对象使用的内存需要至少两次垃圾回收。当垃圾回收器执行回收时,它只回收没有终结器的不可访问对象的内存。这时,它不能回收具有终结器的不可访问对象。它改为将这些对象的项从终止队列中移除并将它们放置在标为准备终止的对象列表中。该列表中的项指向托管堆中准备被调用其终止代码的对象。垃圾回收器为此列表中的对象调用 Finalize 方法,然后,将这些项从列表中移除。后来的垃圾回收将确定终止的对象确实是垃圾,因为标为准备终止对象的列表中的项不再指向它们。在后来的垃圾回收中,实际上回收了对象的内存。


  所以有析构函数的对象,需要两次,第一次调用析构函数,第二次删除对象。而且在析构函数中包含大量的释放资源代码,会降低垃圾回收器的工作效率,影响性能。所以对于包含非托管资源的对象,最好及时的调用Dispose()方法来回收资源,而不是依赖垃圾回收器。
   在一个包含非托管资源的类中,关于资源释放的标准做法是:
   继承IDisposable接口;
   实现Dispose()方法,在其中释放托管资源和非托管资源,并将对象本身从垃圾回收器中移除(垃圾回收器不在回收此资源);
   实现类析构函数,在其中释放非托管资源。
   请看MSDN上的源码  

代码如下:

Public class BaseResource:IDisposable
   {
      PrivateIntPtr handle; // 句柄,属于非托管资源
      PrivateComponet comp; // 组件,托管资源
      Privateboo isDisposed = false; // 是否已释放资源的标志

      PublicBaseResource
      {
      }

       //实现接口方法
       //由类的使用者,在外部显示调用,释放类资源
       Public void Dispose()
       {
           Dispose(true);// 释放托管和非托管资源

          //将对象从垃圾回收器链表中移除,
         // 从而在垃圾回收器工作时,只释放托管资源,而不执行此对象的析构函数

            GC.SuppressFinalize(this);
         }

         //由垃圾回收器调用,释放非托管资源

       ~BaseResource()
        {
           Dispose(false);// 释放非托管资源
        }

     //参数为true表示释放所有资源,只能由使用者调用
    //参数为false表示释放非托管资源,只能由垃圾回收器自动调用
   //如果子类有自己的非托管资源,可以重载这个函数,添加自己的非托管资源的释放
  //但是要记住,重载此函数必须保证调用基类的版本,以保证基类的资源正常释放
    Protectedvirtual void Dispose(bool disposing)
    {
       If(!this.disposed)// 如果资源未释放 这个判断主要用了防止对象被多次释放
         {
            If(disposing)
            {
               Comp.Dispose();// 释放托管资源
             }

           closeHandle(handle);// 释放非托管资源
           handle= IntPtr.Zero;
           }
          this.disposed= true; // 标识此对象已释放
      }
  }


    
 
 

您可能感兴趣的文章:

  • C#垃圾回收机制的详细介绍
  • Python类的构造函数,析构函数以及垃圾回收机制详细介绍及代码举例
  • “当某个实例不再被任何对象引用时就会被垃圾回收机制回收”,那么怎样才算是不被任何对象引用呢?
  • 急!垃圾回收的问题!
  • 垃圾回收器 bdw-gc
  • 关于垃圾回收的问题
  • 垃圾回收的問題
  • 垃圾回收器:gc()的细节,请讨论
  • php垃圾回收机制解析
  • scjp的垃圾回收几个小东东
  • 我时用jdbc打开数据库,使用后是否要显示的关闭数据库,还是等java的垃圾回收器来处理。
  • 我的机器崩溃拉!no stack trace available怎么解决??强制垃圾回收也不行!
  • 关于构造器和垃圾回收器
  • 垃圾回收日志文件分析工具 GCViewer
  • 基于java中stack与heap的区别,java中的垃圾回收机制的相关介绍
  • SQL Server误区30日谈 第18天 有关FileStream的存储,垃圾回收以及其它
  • php析构函数与垃圾回收机制
  • Python的垃圾回收机制深入分析
  • 深入java垃圾回收的详解
  • Java中垃圾回收器GC对吞吐量的影响测试
  • 详谈.net中的垃圾回收机制
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • CCNIC-垃圾-垃圾-垃圾
  • 用Linux发的邮件被当成垃圾邮件
  • ubuntu垃圾清理
  • 邮件反病毒和反垃圾网关 SAGATOR
  • 反垃圾邮件系统 SpamAssassin
  • 防垃圾留言插件 Akismet
  • WordPress反垃圾插件 Defensio Anti-Spam
  • 发垃圾邮件系统 SpamCheck
  • 垃圾收集器 bdwgc
  • WordPress防垃圾留言插件 SpamBam
  • 垃圾信息过滤插件 stop-spam
  • 反垃圾留言插件 WP-Ban
  • linux会产生垃圾文件吗?
  • WP的反垃圾插件 WangGuard
  • 怎么用javamail彻底删除邮件。不是放到垃圾箱里。。
  • 反垃圾邮件系统 milter manager
  • 反垃圾邮件系统 Rspamd
  • WordPress防垃圾留言插件 DNS-anti-spam
  • 垃圾邮件过滤 phPOP3clean
  • WordPress防垃圾留言插件 WP-Gatekeeper


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    sqlserver iis7站长之家