dotnet学习笔记五 - 无用资源回收之二

原创 2003年07月21日 08:14:00

l         Fina<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />lize<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

在上一篇文章中我分配使用资源一共五步,我们已经知道了GC是如何释放无用对象的内存了。但是它怎么实现第四步清空资源使用状态、释放利用到的一些非内存的系统资源呢?.NET引入了Finalize来完成这个任务。

GC在无用单元回收时一旦发现某个对象有Finalize方法,便调用它。所以我们的Finalize方法一定要尽量少做事情,以提高内存回收的速度。另外,在Finalize方法中不要有任何的线程同步等操作,以防止GC线程被挂起。

我们可以用两种方法来写自己的Finalize方法。一种就是显示的实现,如下面的代码:

代码1

public class SomeClass

{

   public SomeClass()

   {

   }

 

   protected override void Finalize()

   {

      Console.WriteLine(“Finalizing…”);

   }

}

使用这种方法时要注意一点,.NET不会帮你做调用基类的Finalize方法。如果需要调用基类的Finalize方法,需要显示的调用。如下面代码:

代码2

public class SomeClass

{

   public SomeClass()

   {

   }

 

   protected override void Finalize()

   {

      Console.WriteLine(“Finalizing…”);

      base.Finalize(); // 调用基类Finalize方法

   }

}

另外一种方法就是析构函数。C#中的析构函数不同于C++。我们看下面的代码:

代码3

public class SomeClass

{

   public SomeClass()

   {

   }

 

   ~SomeClass()

   {

      Console.WriteLine(“Finalizing…”);

   }

}

它等同于代码2

使用Finalize方法要特别小心。因为使用Finalize方法的对象要比普通的对象花时间;GC也要花更多的时间来回收。而且CLR并不能保证调用Finalize的顺序,所以如果对象间有关联(比如一个成员变量先被Finalize了,如果在Finalize方法里还使用它,就会出错),就会更麻烦。

GC是如何实现Finalize的呢?GC维护了两个队列,Finalization队列和Freachable队列。在托管堆分配对象的时候,GC如果发现这个对象实现了一个Finalize方法,就把它加到Finalization队列。如图:

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />CSDN_Dev_Image_2003-7-202213090.jpg

当托管堆的内存不足的时候,GC开始对堆进行回收。GC回收一个对象前,先检查Finalization队列中是否有这个对象的指针,如果有,就将其放入Freachable队列。Freachable队列被认为是根(root)的一部分,所以GC不会对其作回收。GC第一次回收后,堆如下图:

CSDN_Dev_Image_2003-7-202213092.jpg

对象G和对象E不在根的范围之内,被回收。对象F和对象C由于需要Finalize被放入到Freachable队列,这个队列被认为是根的一部分,所以这是对象F和对象C就复活了,没有被GC回收。Freachable队列中的对象的Finalize方法被一个特殊的线程执行。这个线程平时处于非活动状态,一旦Freachable队列不再为空,它就醒过来,一一执行这个队列中对象中的Finalize方法。执行过后如下图:

CSDN_Dev_Image_2003-7-202213094.jpg

这时对象F和对象C不再是根的一部分,如果此时GC进行回收,将会被认作无用对象进行回收,回收后如下图:

CSDN_Dev_Image_2003-7-202213096.jpg

上面简单描述了Finalize作用及其内部的工作原理。下面来说一下Generation

l         Generation

每次都对整个对进行搜索,压缩是非常耗时的。微软总结了一些过去的开发中出现的现象,其中有一条就是,越是新的对象,越是最快被丢弃不再使用。微软根据这个经验在内存回收中引入了Generation的概念,我此处暂时将其翻译成代。托管堆开始的时候是空的,程序启动开始在其中分配对象,这时候的对象就是第0(Generation 0)对象。如下图:

CSDN_Dev_Image_2003-7-202213098.jpg

接下来,到托管堆空间不足,GC进行了第一次回收,剩下的没有被回收的对象就升为第一代,之后再新分配的对象就是第0代(图甲)。再之后GC再进行回收的话只回收第0代,未被回收的第0代升级为第一代,原来的第一代升级为第0代(图乙)。

CSDN_Dev_Image_2003-7-2022130910.jpgCSDN_Dev_Image_2003-7-2022130912.jpg

GC缺省的代(Generation)最高就是2,升级到第二代就不会再升级了。那什么时候GC回收第一,第二代呢?当GC回收完第0代后,发现内存空间还不够,就会回收第一代,回收完第一代,还不够,就回收第二代。

这一篇也写了不少了,所以下一篇再继续,下一篇写WeakReference和如何在自己的代码中控制GC的动作。

dotnet学习笔记五 - 无用资源回收之二

  • zgqtxwd
  • zgqtxwd
  • 2008年04月24日 11:48
  • 137

dotnet学习笔记六 - 无用资源回收之三

这篇文章接着上一次的来,继续讨论无用资源回收的其它一些话题。l         WeakReference(弱引用)我们平常用的都是对象的强引用,如果有强引用存在,GC是不会回收对象的。我们能不能同时...
  • kenli
  • kenli
  • 2003年07月24日 15:57
  • 1684

dotnet学习笔记四 - 无用单元回收

  • zgqtxwd
  • zgqtxwd
  • 2008年04月24日 15:29
  • 91

数据结构实验之二叉树五:层序遍历

题目描述 已知一个按先序输入的字符序列,如abd,,eg,,,cf,,,(其中,表示空结点)。请建立二叉树并求二叉树的层次遍历序列。 输入  输入数据有多行,第一行是一个整数t (t,代...
  • zhang_di233
  • zhang_di233
  • 2015年11月05日 21:36
  • 917

sdut oj3344 数据结构实验之二叉树五:层序遍历

题目链接:点击打开链接 数据结构实验之二叉树五:层序遍历 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ ...
  • Annfan123
  • Annfan123
  • 2016年08月08日 20:55
  • 166

sdutacm-数据结构实验之二叉树五:层序遍历

山东理工acm平台题解
  • axuhongbo
  • axuhongbo
  • 2017年03月06日 12:59
  • 109

数据结构实验之二叉树五:层序遍历 oj

数据结构实验之二叉树五:层序遍历 Time Limit: 1000MS Memory Limit: 65536KB Problem Description 已知一个按先序输入的字符序...
  • sdut_jk17_zhangming
  • sdut_jk17_zhangming
  • 2018年01月23日 09:00
  • 42

3346数据结构实验之二叉树七:叶子问题

 数据结构实验之二叉树七:叶子问题 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 已知一个按...
  • femalcoder
  • femalcoder
  • 2016年08月08日 20:58
  • 274

AndroidStudio清除无用的资源

AndroidStudio清除无用的资源
  • zhangquanit
  • zhangquanit
  • 2016年12月11日 00:31
  • 6196

android之as自动化删除无用资源为apk瘦身

随着项目越来越大,一些无用的资源越来越多,有必要为apk瘦身了,网上一顿乱拔,有欢喜也有泪水,唉,要么是搭建python环境太复杂,要么是没有适用于android studio项目的自动化删除无用资源...
  • zhongwn
  • zhongwn
  • 2016年10月09日 20:29
  • 2535
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:dotnet学习笔记五 - 无用资源回收之二
举报原因:
原因补充:

(最多只允许输入30个字)