部分回收概述

一个基本的事实是,对象通常“英年早逝”。人们发现,通常80%-98%的新分配对象在几百万条指令之内,或者在再分配了另外的几兆字节之前就消亡了。也就是说,对象通常在垃圾回收过程启动之前就已经变得不可达了。因此,频繁地对新对象进行垃圾具有相当高的性价比。

然而,经历了一次回收的对象很可能在多次回收之后依然存在。在迄今为止描述的垃圾回收器中,同一个成熟对象会在各轮垃圾回收中被发现是可达的。如果使用拷贝回收器,这些对象会在各轮垃圾回收中被一次次地拷贝。世代回收在包含最年轻对象的堆区域中的回收工作最为频繁,所以它通常可以用相对较少的工作量回收大量的垃圾。另一方面,列车算法没有在年轻对象上花费太多的时间,但是它能够有效限制因垃圾回收而造成的程序停顿时间。因此,将这两个策略合并的好方法是对年轻对象使用世代回收,而一旦一个对象变得相当成熟,则将它“提升”到一个由列车算法管理的独立堆区中。

短停顿垃圾回收

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

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

并行垃圾回收算法

我们必须控制启动跟踪过程的频率,这很重要。跟踪步骤就像是一场赛跑。增变者创建出必须被扫描的新对象和新引用,而跟踪过程则试图扫描所有可达对象,并重新扫描同时产生的脏卡片。
下面给出一个并行、并发垃圾回收算法的大概描述,我们可以仔细看一下,:

1)扫描每个增变者线程的根集,将所有可以从根集中直接到达的对象设为待扫描状态。完成这一步的最简单的增量式做法是等待一个增变者线程调用内存管理器,如果那时它的根集还没有被扫描,就让它扫描自己的根集。如果所有其他跟踪工作都已经完成,而某个增变者线程还没有调用内存分配函数,那么必须暂停这个线程,扫描它的根集。

«1»
最近发表
控制面板
您好,欢迎到访网站!
  [查看权限]
网站分类
搜索
Tags列表
网站收藏
图标汇集
  • 订阅本站的 RSS 2.0 新闻聚合
友情链接

热门搜索: 外链域名 高外链域名 高收录域名

Copyright www.thyst.cn. Some Rights Reserved.