就是只把某个空间里的活动对象复制到其他空间,把原空间里的所有对象都回收掉
heap分为from和to两个空间,当fron空间被占满时,GC会把活动对象全部复制到to空间。当复制完成后,该算法会把 From 空间和 To 空间互换,GC 也就结束了。From 空间和 To 空间大小必须一致。
对应的复制函数
copying(){
$free = $to_start
for(r : $roots)
*r = copy(*r)
swap($from_start, $to_start)
}
copy(obj){
if(obj.tag != COPIED)
copy_data($free, obj, obj.size)
obj.tag = COPIED
//forwarding指针存储了此对象to空间对应复本的指针
obj.forwarding = $free
$free += obj.size
//把新空间对象的子对象进行递归copy操作
for(child : children(obj.forwarding))
*child = copy(*child)
return obj.forwarding
}
对应的复制算法的申请内存操作很简单,如果当前空间够的话,直接在后面累加就行了,不够就进行copying操作:
new_obj(size){
if($free + size > $from_start + HEAP_SIZE/2)
copying()
if($free + size > $from_start + HEAP_SIZE/2)
allocation_fail()
obj = $free
obj.size = size
$free += size
return obj
}
优点
- 吞吐量优秀
- 可实现告诉分配:分配内存的时候在末尾累加就行了
- 没有碎片化问题
- 与缓存兼容:有引用关系的内存间距离很近,一般都是挨着的
缺点
- heap使用效率低