CLR垃圾回收

垃圾回收算法:

第一阶段:垃圾回收的第一阶段是标记(marking)。在这个阶段中,垃圾回收器杨喆线程栈上行以检查所有的根。如果发现了一个根引用了一个对象,就在对象的“同步块索引字段”上开启标记。检查好所有的根之后,堆中将包含一组已标记和未标记的对象。已标记的对象是通过应用程序的代码可达的对象,而未标记的对象是不可达的。不可达的被认为是垃圾。

第二阶段:垃圾回收的第二阶段是压缩(compact)在这个阶段中,垃圾回收器线性的遍历堆,以寻找未标记(垃圾)对象的连续内存块。如果发现的内存块比较小,垃圾回收器就忽略它们。但是如果发现大的、可用的连续内存块,垃圾回收器会把非垃圾的对象移动到这里进行压缩。压缩之后,之前的变量和CPU寄存器中的地址将会变得无效。所以垃圾回收器必须重新访问应用程序的所有根,并修改它们来只想对象的新内存的位置。

 

Finalize方法:

调用Finalize方法来清理对象中使用的本地资源(文件、网络连接、数据库连接等)。应该注意的是,调用Finalize并不是立即释放内存。Finalize方法在垃圾回收结束时调用,有以下5种事件会导致开始垃圾回收:

  • 第0代满时,垃圾回收自动开始
  • 代码显示调用System.GC的静态方法Collect,显示请求 CLR执行垃圾回收
  • Windows报告内存不足
  • CLR卸载AppDomain时,CLR认为该AppDomain中不再存在任何根,因此会对所有代的对象执行垃圾回收
  • CLR关闭,CLR认为该进程中不存在任何根,所以会调用托管堆中的所有对象的Finalize方法,但CLR不会进行压缩或者释放内存,因为整个进程都要终止,将由Windows负责回收进程的所有内存

 

终结列表:

终结列表是由垃圾回收器控制的一个内部数据结构。应用程序创建一个新对象时,new操作符会从堆中分配内存。如果对象的类型定义了Finalize方法,那么在该类型的实例构造器被调用之前,会将指向该类型的一个指针放到终结列表里去。列表中的每一项都指向一个对象,在回收该对象的内存之前,应调用它的Finalize方法

 

Dispose模式:

和Finalize类似,Dispose模式也是用于清理本地资源。不同的是,Fianlize只能由CLR在进行垃圾回收的时候调用,而Dispose可以由代码显示的来调用。同理,调用了Dispose后,对象持有的内存也不会被释放。

 

代:

代是CLR垃圾回收器采用的一个机制。基于代的垃圾回收器,基于下面的假设:

  • 对象越新,生存期越短
  • 对象越老,生存期越长
  • 回收堆的一部分,速度快于回收整个堆

第0代:

托管堆在初始化时不包含任何对象。添加到堆的对象称为第0代对象。第0代对象就是新构建的对象。CLR初始化时,它为第0代选择一个预算容量,假定为256KB,实际肯呢个不同。如果分配一个新的对象造成第0代超过预算,就必须启动一次垃圾回收。

posted @ 2012-09-03 23:45  HelloWorld.Michael  阅读(457)  评论(0编辑  收藏  举报