1 引用跟踪算法


CLR使用一种引用跟踪算法来确实对象是否回收。

2 根


所有引用类型的变量都叫根。

3 活动根


活动根分为三种:

  1. 当前正在执行的方法(或在其调用栈的任何一个方法中) 的局部变量或者参数;
  2. 静态变量;
  3. 终结队列中的对象。

4 垃圾回收过程


  • 标记阶段
    CLR 遍历堆中所有对象,将同步块索引字段中的一位设为0。然后检查所有的活动根,及其引用的对象,将其同步块索引字段中的一位设为1(可达的)。不可达的对象将会被回收。
  • 压缩阶段
    将幸存下来的对象,紧密排列,并修正引用。压缩避免堆的碎片化。

5 代


CLR 的 GC 是基于代的垃圾回收器,对代码做了三个假设:

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

大体过程如下:

  • CLR 初始化时,所有对象都是第0代,并给选择一个预算容量(几百KB到几M);
  • 随着程序的运行,如果分配一个新对象造成第0代超预算,就启动GC;
  • 启动GC后,会检查第1代占用了多少内存,如果超出第1代的预算,就会回收第1代和第0代所有不可达对象;
  • 第0代幸存的对象提升至第1代,第1代幸存对象提升至第2代。

6 垃圾回收的触发条件


  • 第0代超出预算;
  • 显示调用GC.Collect()方法;
  • Windows 报告低内存;
  • CLR 卸载AppDomain;
  • CLR 关闭。

7 垃圾回收模式

  • 工作站
  • 服务器