background image

  大多数垃圾回收算法使用了根集(root set)这个概念;所谓根集就量正在执行的 Java
程序可以访问的引用变量的集合(包括局部变量、参数、类变量),程序可以使用引用变量
访问对象的属性和调用对象的方法。垃圾收集首选需要确定从根开始哪些是可达的和哪些
是不可达的,从根集可达的对象都是活动对象,它们不能作为垃圾被回收,这也包括从
根集间接可达的对象。而根集通过任意路径不可达的对象符合垃圾收集的条件,应该被回
收。下面介绍几个常用的算法。

  1  

、 引用计数法(Reference Counting Collector)

  引用计数法是唯一没有使用根集的垃圾回收的法,该算法使用引用计数器来区分存
活对象和不再使用的对象。一般来说,堆中的每个对象对应一个引用计数器。当每一次创
建一个对象并赋给一个变量时,引用计数器置为 1。当对象被赋给任意变量时,引用计数
器每次加 1 当对象出了作用域后(该对象丢弃不再使用),引用计数器减 1,一旦引用计数
器为 0,对象就满足了垃圾收集的条件。

 

  基于引用计数器的垃圾收集器运行较快,不会长时间中断程序执行,适宜地必须 实
时运行的程序。但引用计数器增加了程序执行的开销,因为每次对象赋给新的变量,计数
器加 1,而每次现有对象出了作用域生,计数器减 1。

  2、tracing 算法(Tracing Collector)

  tracing 算法是为了解决引用计数法的问题而提出,它使用了根集的概念。基于 tracing
算法的垃圾收集器从根集开始扫描,识别出哪些对象可达,哪些对象不可达,并用某种
方式标记可达对象,例如对每个可达对象设置一个或多个位。在扫描识别过程中,基于
tracing 算法的垃圾收集也称为标记和清除(mark-and-sweep)垃圾收集器.

  3、compacting 算法(Compacting Collector)

  为了解决堆碎片问题,基于 tracing 的垃圾回收吸收了 Compacting 算法的思想,在清
除的过程中,算法将所有的对象移到堆的一端,堆的另一端就变成了一个相邻的空闲内
存区,收集器会对它移动的所有对象的所有引用进行更新,使得这些引用在新的位置能
识别原来的对象。在基于 Compacting 算法的收集器的实现中,一般增加句柄和句柄表。

  4、copying 算法(Coping Collector)