C#清理非托管对象实例分析

本文实例讲述了C#清理非托管对象的方法。分享给大家供大家参考,具体如下:

Finalize方式在.net内部是如何实现的呢?

当GC(垃圾回收器)开始工作的时候,它首先将没有终结器的垃圾对象从内存中移除,有终结器的所有对象则添加到一个终止化队列当中。GC会调用一个 新线程来执行这些对象的终结器。当终结器执行完毕后,这些对象会从队列中被移除。这时候由于这些对象在第一次检测到的时候没有被释放,它们将会进入第1代 对象,直到GC检测到第0代对象和第1代对象再次充满时,这时候GC才会把刚才那些对象释放掉,所以有终结器的对象会比没有的在内存中保留更长的时间。

提示:垃圾回收器把托管堆中的对象分为3代,分别是0,1,2.一般分配为:0代约256K,1代约是2MB,第2代约是MB,代龄越高,容量就越 大,显然效率也就越低.首先被添加到托管堆中的对象被定为第0代,当第0代充满时,就会执行垃圾回收,未被回收的对象代领将提升1代.

由于以上原因应该避免仅使用Finalize方式释放非托管资源.

Dispose模式:在自定义类中实现IDispose接口,在接口中的Dispose方法中对非托管资源进行释放.闲话少说,上代码

public class MyResourceRelease: IDisposable
{
  /// 保证资源只用释放一次
  private bool _alreadyDisposed = false;
  /// 用来判断释放资源的类别(托管和非托管)
  protected virtual void Dispose(bool isDisposing)
  {
    if(_alreadyDisposed)
    {
      return;
    }
    if(isDisposing)
    {
      //释放托管资源
    }
    //释放非托管资源
    _alreadyDisposed = true;
  }
  public void Dispose()
  {
    Dispose(true);
  }
}

上面的代码就是用Dispose方式释放资源的方法.因为上面自定义的Dispose(bool isDisposing)方法是virtual的,所以还可以在派生类里面对它进行override

public class MyDerivedResource: MyResourceRelease
{
  private bool _disposed = false;
  protected override void Dispose(bool isDisposing)
  {
    if(_disposed)
    {
      return;
    }
    try
    {
      if(isDisposing)
      {
       //释放托管资源
      }
      //释放非托管资源
      _disposed = true;
     }
     finally
     {
     base.Dispose(isDisposing);
     }
  }
}

这样可以确保释放继承链上所有对象的引用资源,在整个继承层次中传播Dispose模式

更多关于C#相关内容感兴趣的读者可查看本站专题:《C#数据结构与算法教程》、《C#常见控件用法教程》、《C#面向对象程序设计入门教程》及《C#程序设计之线程使用技巧总结》

希望本文所述对大家C#程序设计有所帮助。

(0)

相关推荐

  • C#托管堆对象实例包含内容分析

    本文以实例形式分析了C#托管堆对象实例包含的内容,有助于进一步了解C#程序设计中的托管对象.分享给大家供大家参考.具体分析如下: 通常来说,每个托管堆上的对象实例除了包含本身的值外,还包括: ① Type Object Ponter: 指向Type对象实例.如果是同类型的对象实例,就指向同一个Type对象实例. ② Sync Block Index:在多线程情况下用来控制同步 如下实例所示: namespace ConsoleApplication1 { class Program { stat

  • C#使用非托管代码直接修改字符串的方法

    复制代码 代码如下: using System; public class Test{ public static void Main(string[] args) {  string str = "hello";  ToUpper(str);  Console.WriteLine(str); } private static unsafe void ToUpper(string str) {  fixed(char * pfixed = str)  for(char * p=pfix

  • 如何批量清理系统临时文件(语言:C#、 C/C++、 php 、python 、java )

    语言之争由来已久,下面做一些IO实验(遍历9G多的文件,批量删除),尽量用事实来比较谁优谁劣.操作系统:win7 64 位,文件包大小:9.68G. 一.语言:C# 开发环境:vs 2013 代码总行数:43行 耗时:7秒 代码: using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; n

  • c#自带缓存使用方法 c#移除清理缓存

    复制代码 代码如下: /// <summary>/// 获取数据缓存/// </summary>/// <param name="CacheKey">键</param>public static object GetCache(string CacheKey){    System.Web.Caching.Cache objCache = HttpRuntime.Cache;    return objCache[CacheKey];}/

  • C#控制IE进程关闭和缓存清理的实现代码

    复制代码 代码如下: class IEUtil {    public static void openIE(string url) {        try {            //System.Diagnostics.Process.Start(url);            System.Diagnostics.Process p = new System.Diagnostics.Process();            p.StartInfo.FileName = "iexpl

  • C#使用DllImport调用非托管的代码的方法

    找到GetShortPathName的方法签名, DWORD GetShortPathName(LPCTSTR tpszLongPath,TPTSTR lpszShortPath,DWORD cchBuffer): 非托管及托管数据类型对应关系: LPCTSTR         String LPTSTR           StringBuilder DWORD          int DllImport的导入规则: 1.方法名与Win API完全一样.如果在C#中调用时显示完全不同的方法名

  • C#调用非托管动态库中的函数方法

    C#如何调用一个非托管动态库中的函数呢,比如用VC6写的动态库,总之C#调用动态库的过程是比Java调用DLL动态库方便快捷多了,下面举例说明这个过程. 1.创建一个非托管动态库 代码如下: 复制代码 代码如下: //这一句是声明动态库输出一个可供外不调用的函数原型.     extern   "C"  __declspec(dllexport)  int  add( int ,  int ); int  add( int  a, int  b)      {          //实

  • 详解C# 托管资源和非托管资源

    托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源.托管资源的回收工作是不需要人工干预的,有.NET运行库在合适调用垃圾回收器进行回收. 非托管资源指的是.NET不知道如何回收的资源,最常见的一类非托管资源是包装操作系统资源的对象,例如文件,窗口,网络连接,数据库连接,画刷,图标等.这类资源,垃圾回收器在清理的时候会调用Object.Finalize()方法.默认情况下,方法是空的,对于非托管对象,需要在此方法中编写回收非托管资源的代码,以便垃圾回收器正确回收资源. 在

  • C#清理非托管对象实例分析

    本文实例讲述了C#清理非托管对象的方法.分享给大家供大家参考,具体如下: Finalize方式在.net内部是如何实现的呢? 当GC(垃圾回收器)开始工作的时候,它首先将没有终结器的垃圾对象从内存中移除,有终结器的所有对象则添加到一个终止化队列当中.GC会调用一个 新线程来执行这些对象的终结器.当终结器执行完毕后,这些对象会从队列中被移除.这时候由于这些对象在第一次检测到的时候没有被释放,它们将会进入第1代 对象,直到GC检测到第0代对象和第1代对象再次充满时,这时候GC才会把刚才那些对象释放掉

  • C#静态方法与非静态方法实例分析

    本文实例分析了C#静态方法与非静态方法,并对其用法进行了较为全面的分析.分享给大家供大家参考.具体分析如下: 通常来说,C#的类中可以包含两种方法:静态方法和非静态方法. 使用了static 修饰符的方法为静态方法,反之则是非静态方法. 静态方法是一种特殊的成员方法,它不属于类的某一个具体的实例,而是属于类本身.所以对静态方法不需要首先创建一个类的实例,而是采用 类名.静态方法 的格式 . 1)static方法是类中的一个成员方法,属于整个类,即不用创建任何对象也可以直接调用. static内部

  • php 多进程编程父进程的阻塞与非阻塞实例分析

    本文实例讲述了php 多进程编程父进程的阻塞与非阻塞.分享给大家供大家参考,具体如下: php中进程的阻塞,主要是父进程等待子进程退出. 1.php代码如下: <?php //定义进程数量 define('FORK_NUMS', 5); //用于保存进程pid $pids = array(); //我们创建5个子进程 for ($i = 0; $i < FORK_NUMS; ++$i) { $pids[$i] = pcntl_fork(); if ($pids[$i] == -1) { die

  • Vue常用传值方式、父传子、子传父及非父子实例分析

    本文实例讲述了Vue常用传值方式.父传子.子传父及非父子.分享给大家供大家参考,具体如下: 父组件向子组件传值是利用props 子组件中的注意事项:props:['greetMsg'],注意props后面是[]数组可以接收多个值,不是{}. 且此处的greetMsg用greet-msg会报错,记住需用驼峰法命名 非父子组件进行传值 非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中 间仓库来传值,不然路由组件之间达不到传值的效果. import Vue from 'vue' e

  • C#资源释放方法实例分析

    本文实例讲述了C#资源释放方法.分享给大家供大家参考,具体如下: 1.try{}finally{} 2.using 只有类型实现了IDisposable接口并且重写Dispose()方法可以使用using语句实现资源释放. 首先来看MSDN中关于这个接口的说明: [ComVisible(true)] public interface IDisposable { // Methods void Dispose(); } 1.[ComVisible(true)]: 指示该托管类型对 COM 是可见的

  • JQuery中Ajax()的data参数类型实例分析

    本文实例分析了JQuery中Ajax()的data参数类型.分享给大家供大家参考,具体如下: 前面简单分析介绍了<ajax中data传参的两种方式>,对于ajax参数传递方式有了初步的了解,这里就来进一步分析一下ajax中data参数的类型. 假如现在有这样一个表单,是添加元素用的. <form id='addForm' action='UserAdd.action' type='post'> <label for='uname'>用户名</label>:&

  • Java集合ArrayDeque类实例分析

    Java集合ArrayDeque类实例分析 前言 ArrayDeque类是双端队列的实现类,类的继承结构如下面,继承自AbastractCollection(该类实习了部分集合通用的方法,其实现了Collection接口),其实现的接口Deque接口中定义了双端队列的主要的方法,比如从头删除,从尾部删除,获取头数据,获取尾部数据等等. public class ArrayDeque<E> extends AbstractCollection<E> implements Deque&

  • CodeIgniter配置之config.php用法实例分析

    本文实例分析了CodeIgniter配置之config.php用法.分享给大家供大家参考,具体如下: 配置说明 $config['language']:指定项目语言包.需要注意的时Codeigniter自带的类库错误提示语言包位于/system/language/english/目录下,当这里配置非english时, 如果需要用到这些类库,则需要拷贝语言包到指定的目录中,否则会出现load出错. $config['charset']:设置系统使用的编码,在某些需要指定编码的函数中会用到,系统.数

  • CI(CodeIgniter)模型用法实例分析

    本文实例分析了CI(CodeIgniter)模型用法.分享给大家供大家参考,具体如下: MVC中的业务逻辑放在控制器中或者模型里都是不合适的,所以这里对业务逻辑进行了分离,多出一层用来处理业务逻辑,模型就只当作数据访问层,这样子模型将会变得比较轻.CI中并未通过实体对象来传参,参数的传入和返回都由开发者控制,比较灵活.很多情况下都会以数组的方式传入或者返回. 模型的使用也比较简单,这里只提一下使用前想到的几个问题吧. 1.既然已经有了数据访问层了,那我们就应当避免在控制器或者某些类中直接通过SQ

  • MySQL数据库的一次死锁实例分析

    1.故事起因于2016年11月15日的一个生产bug.业务场景是:归档一个表里边的数据到历史表里边,同是删除主表记录. 2.背景场景简化如下(数据库引擎InnoDb,数据隔离级别RR[REPEATABLE]) -- 创建表test1 CREATE TABLE test1 ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(10) NOT NULL, PRIMARY KEY (id) ); insert into test1 values('hel

随机推荐