« 上一篇下一篇 »

运行环境之列车算法

尽管世代方法处理年轻对象时非常高效,但它在处理成熟对象时却相对低效,因为每当一个垃圾回收过程涉及某个成熟对象时,该对象都会被移动,而且它们不太可能变成垃圾。另一种 被称为列车算法的增量式回收方法用于改进对成熟对象的处理。它可以用来回收所有的垃圾。 但是更好的方法是使用世代方法来处理年轻的对象,只有当这些对象经历了几轮世代回收之后仍然存在,才将它们提升到另一个由列车算法管理的堆区。列车算法的另一个优点是我们永远不需要进行全面的垃圾回收过程,而在世代垃圾回收中却仍然必须偶尔那样做。

为了描述列车算法的动机,我们首先看一个简单的例子。该例子告诉我们为什么在世代方法中必须偶尔进行一轮全面的垃圾回收。给出了位于两个区域i和j中的两个相互连接的对象,其中j>i。因为这两个对象都有来自其区域之外的指针,只对区域i或只对区域j进行回收都不能回收这两个对象。然而,它们可能实际上是一个循环垃圾结构中的一部分,没有外部链接指向该垃圾结构。一般来说,这里显示的对象之间的“链接”可能涉及很多对象和一条很长的引用链。

在世代垃圾回收中,我们最终会回收区域j,并且因为i

列车算法使用固定大小的被称为车厢(car)的区域。当没有对象比磁盘块更大时,一节车厢可以是一个磁盘块,否则可以将车厢的尺寸设得更大。但是车厢的大小一旦确定就不再变化。多节车厢被组织成列车(train)。一辆列车中的车厢数量没有限制,且列车的数量也没有限制。车厢之间按照词典顺序进行排序:首先以列车号排序,在同一列车中则以车厢号排序,列车算法有两种回收垃圾的方式:

*在一个增量式垃圾回收步骤中,按照词典顺序排列的第一节车厢(即尚存的第一辆列车中尚存的第一节车厢)首先被回收。因为我们保留了一个来自该车厢之外的所有指针的“被记忆”列表,所以这一步类似于世代算法中针对第一个区域的回收步骤。这里我们确定出没有任何引用的对象,以及完全包含在这节车厢里的垃圾循环。该车厢中的可达对象总是被移至其他的某个车厢中,因此每个被回收过的车厢都变成空车厢,可以从这辆列车中删除。

*有时,第一辆列车没有外部引用。也就是说,没有从根集指向该列车中任何车厢的指针,并且各节车厢中的被记忆集中只有来自本列车的其他车厢的引用,没有来自其他列车的引用。在这种情况下,该列车就是一个巨大的循环垃圾集合,我们可以删除整辆列车。

« 上一篇下一篇 »