非托管资源的释放

  1.托管资源指的是.net可以自动进行回收的资源,由CLR控制,主要是指托管堆上分配的内存资源。托管资源的回收工作是不需要人工干预的,同时,您也无法干预他们的回收。即您的应用程序创建的大多数对象,可以依靠.net framework的垃圾回收器隐式的执行所有必要的内存管理任务。

  2.非托管资源指的是.net不会自动进行垃圾回收,而需要程序员手动去释放的资源。最常见的一类非托管资源是包装操作系统资源的对象,例如:文件,窗口,网络连接,数据库连接,画刷,图标,COM对象等。(对于非托管资源,在应用程序使用后必须显示的释放。例如System.IO.StreamReader的一个文件对象,必须显示的调用对象的Close()方法关闭它,否则会占用系统的内存和资源,可能出现意想不到的错误。)这类资源,垃圾回收器在清理的时候会调用Object.Finalize()方法。默认情况下,方法是空的,对于非托管对象,需要在此方法中编写回收非托管资源的代码,以便垃圾回收器正确回收资源。然而在实际编程中根本无法override  Finalize() 在c#中,可以通过析构函数自动生成Finalize方法和对基类的Finalize方法的调用。

例如:

~Demo()
{
   //Perform some cleanup operations here.      
}

该代码隐式翻译为下面的代码:

protected override void Finalize()
{
    try
    {
         // Perform some cleanup operations here.
    }
    finally
  {
    base.Finalize();
  }
}

  但是在编程中,并不建议进行override方法Finalize(),因为实现Finalize方法或析构函数对性能可能会有负面影响。例如:Finalize()方法回收对象使用的内存需要至少两次垃圾回收,当垃圾器回收时,它只回收没有终结器(Finalize方法)的不可访问的内存。

  它将这些对象的项从终止队列中移除,并将它们放置在标记为“准备终止”的对象列表中,该列表中的项指向 托管堆中准备被调用其终止代码的对象,下次垃圾回收器回收时,就回收并释放了这些内存。

-----------------------------------------------------------------------------------------------------------

  c#托管及未托管对象管理:

  c#中的对象分为值类型和引用类型,二者最大的区别在于数据的存储方式和存储位置,Windows操作系统使用虚拟寻址系统来管理程序运行时产生的数据存放,简单来说,该系统管理者一个内存区域,在该区域中划拨出一部分出来专门存放值类型变量,称为堆栈。

  堆栈采用先进后出的原则,将值类型变量从区域的最高地址为开始,向低位地址存储,先进后出。先进后出的管理方式保证了值类型变量在出了作用域后能及时的清除占用的内存区域。

  由于堆栈的速度快,有非常高的性能,所保存的数据一般不太大,这部分一般不需要用户专门操作。但堆栈对于所有的变量来说还是不太灵活,所以托管堆就出现了。下面是堆栈和托管堆的比较:

堆栈stack:

  1.堆栈中存储值类型

  2.堆栈实际上是向下填充,即由高内存地址向地内存地址填充。

  3.堆栈的工作方式是先分配内存的变量后释放(先进后出原则)。

  4.堆栈中的变量是从下向上释放,这样就保证了堆栈中先进后出的原则不与变量的生命周期起冲突。

  5.堆栈的性能非常高,但是对于所有的变量来说不是很灵活,而且变量的生命周期必须嵌套。

  ---------------------------------------------------------------------------------------------

所以我们希望使用一种方法分配内存来存储数据,并且方法退出后很长一段时间内数据仍然可以使用。这时就要用到堆(托管堆)

托管堆head:

  1.堆(托管堆)存储引用类型。

  2.此堆非彼堆,.net中的堆由垃圾回收器自动管理。

  3.与堆栈不同,堆是从下往上分配,所以自由的空间都在已用的空间上面。

--------------------------------------------------------------------------------------------------

  因为非托管资源一般是有限的,而垃圾回收器由CRL自动调用,这样就无法保证及时的释放掉非托管资源,因此,定义了一个Dispose()方法,让使用者能够手动释放非托管资源。dispose()方法释放类的托管资源和非托管资源,使用者手动调用此方法后,垃圾回收器不会对此类实例再次进行回收。

  Microsoft为非托管资源的回收专门定义了一个接口:IDisposable,接口中只包含一个Dispose()方法。任何包含非托管资源的类,都应该继承此接口。

原文地址:https://www.cnblogs.com/miaoying/p/5521508.html