« 上一篇下一篇 »

短停顿垃圾回收

简单基于跟踪的回收器是以全面停顿的方式进行垃圾回收的,它可能造成用户程序运行的长时间的停顿。我们可以每次只做部分垃圾回收工作,从而减少一次停顿的长度。我们可以按照时间来分割工作任务,使垃圾回收和增变者的运行交错进行。我们也可以按照空间来分割工作任务,每次只完成一部分垃圾的回收。前者称为增量式回收(incremental collection),后者称为部分回收(partial collection)。

增量式回收器将可达性分析任务分割成为若干个较小单元,并允许增变者和这些任务单元交错运行。可达集合会随着增变者的运行发生变化,因此增量式回收是很复杂的。我们将看到,寻找一个稍微保守的解决方法将使得跟踪更加髙效。

最有名的部分回收算法是世代垃圾回收(generational garbage collection)。它根据对象已分配时间的长短来划分对象,并且较频繁地回收新创建的对象,因为这些对象的生命周期往往较短。 另一种可选的算法是列车算法(train algorithm),也是每次只回收一部分垃圾。它最适合回收较成熟的对象。这两个算法可以联合使用,构成一个部分回收器。这个回收器使用不同的方法来处理较新的和较成熟的对象。我们将在讨论有关部分回收的基本算法,然后详细地描述世代算法和列车算法的工作原理。

来自于增量回收算法和部分回收算法的思想经过修改,可以用于构造一个在多处理器系统中并行回收对象的算法。

被记忆集

现在我们给出列车算法的细节。每节车厢有一个被记忆集,它由指向该车厢中对象的引用组成,这些引用来自:

1)同一辆列车中序号较高的车厢中的对象,以及

2)序号较高的列车中的对象。

此外,每辆列车有一个被记忆集,它由来自较高序号列车中的引用组成。也就是说,一个列 车的被记忆集是它内部的所有车厢的被记忆集的并集,但是不包含列车内部的引用。因此,可以 将车厢的被记忆集划分成“内部”(同一列车)和“外部”(其他列车)两个部分,同时表示这两种不 同类型的被记忆集。

注意,指向这些对象的引用可以来自各个地方,不只是来自按字典顺序排列的序号较高的车厢。然而,算法中的两种垃圾回收过程分别处理第一辆列车的第一节车厢和整个第一辆列车。 因此,当在垃圾回收中需要使用被记忆集的时候,已经没有更早的地方可以有引用到达被处理的 车厢或者列车。因此记录下指向较高序号车厢的引用没有什么意义。当然,我们必须认真、正确 地管理被记忆集,只要增变者改变了任何对象中的引用,就需要相应地改变被记忆集。

« 上一篇下一篇 »