3. GC复制算法

  • 1963年, Marvin L. Minsky 在论文中发布了复制算法

简单的说,GC复制算法就是把某个空间里的活动对象复制到其他的空间,把原空间的所有对象都回收掉。在此,我们将复制活动的原空间称为 From 空间,将粘贴活动对象的空间称为 To 空间。

GC复制算法是利用From空间进行分配的。当 From 空间被完全占满时,GC会将活动对象全部复制到 TO。当复制完成后,该算法会把 From 空间和 To 空间互换。GC也就结束了。

From 空间和 To 空间大小必须一致。这是为了保证能把 From 空间中的所有活动对象都收纳到To空间里。

首先看来看GC复制算法的主要函数 copying()

copying(){
    $free = $to_start # 1
    for(r : $root) 
        *r = copy(*r) # 2
    swap($from_start, $to_start) # 3
}
  1. $free 指分块开头的变量。首先将 $free 设置在To空间的开头。
  2. 复制从根引用的对象及其子对象, 复制结束后返回指向新空间地址的 *r 指针
  3. 将From空间和To空间互换,GC就结束了
copy(obj){
    if(obj.tag != COPIED) # 1
        copy_data($free, obj, obj.size)
        obj.tag = COPIED
        obj.forwarding = $free
        $free += obj.size
        
        for(child : children(obj.forwarding))
            *child = copy(*child)
            
    return obj.forwarding
}
  1. 检查obj的复制是否已经完成,之所以先检查时候已经被复制是为了防止对象被多次引用后发生多次复制的情况。

  2. 如果对象尚未被复制,就复制 obj, 返回指向新空间对象的指针。复制过程如下

    1. 首先用 copy_data() 函数将obj 复制到 $free 空间中,如下图所示,对象A被复制,生成A' 。

posted @ 2020-10-16 00:16  暮晨  阅读(272)  评论(0编辑  收藏  举报

Aaron Swartz was and will always be a hero