整体思路是,将堆分为二等份,当其中一份分配不够时,启动 GC 递归从根节点出发(深度优先),将对象拷贝到另外一半,然后将原先部分全部回收。循环往复。
考虑到对象被引用的复杂性,只有当一个对象被 完全拷贝 完成以后,才会更新指向其的地址。
基础实现
代码
type object struct {
isCopied bool // 用来标记是否已经被复制过
forwarding *object // 在完成拷贝之前,是不能更新对该 obj 的引用的。这是一个暂存的地方
size int
children []*object
data interface{
}
}
func copy(obj *object) *object {
if !obj.isCopied {
copy_data(heapStart, obj, obj.size)
obj.isCopied = true
obj.forwarding = heapStart
heapStart += obj.size
for i, child :=