垃圾回收-标记整理算法的两种实现

本文探讨了标记整理算法的两种实现方式——Lisp2算法和双指针算法。Lisp2算法包括标记和压缩两个阶段,通过设置forwarding指针实现对象移动。双指针算法则利用两个指针移动对象并更新子对象指针,要求对象大小一致。这两种算法相比其他GC算法,能有效避免内存碎片,但可能导致吞吐量较小。
摘要由CSDN通过智能技术生成

导语

传统gc算法有:标记清除,复制算法,标记整理等。它们各有优点,标记整理的优点就是空间整理功能。本文主要介绍标记整理算法的两种实现方式。

前言

  • 活动对象:可以存活的对象
  • 非活动对象:可以被回收的对象
  • 算法以伪代码表示

Lisp2 算法

Lisp算法包括两个阶段

  1. 标记
  2. 压缩
  • 标记阶段:选取gc根对象。从这些对象开始向下遍历其子对象,最终可能会形成一个又向有环图。在此图中的对象就是活动对象,也就是将要压缩的对象。

  • 整理阶段:将对象向着一端移动,移动后对象的相对顺序不变,但是对象紧临。

比如:在垃圾回收前:有ABCDEF五个对象,可以看出A和E是非活动对象。其中根引用了B和D,B引用了C,D引用了F

标记整理-初始状态

标记结束后:
标记整理-标记后

在垃圾回收后:
标记整理-整理后

标记阶段算法

选取gc roots,然后以深度优先或者广度优先的方式遍历。

mark_phase(){
   
    for(r : $roots)
        mark(*r)
}

mark(obj){
   
    if(obj.mark == FALSE)
        obj.mark = TRUE
        for(child : children(obj))
            mark(*child)
}

$roots为gc roots,mark是对象头的标记位

标记的时候可以在对象头上标记,但是这样与写时复制不兼容。当复制了一个对象,还不需要写的时候开始gc,那么就必须进行对象复制操作。为了解决这个问题可以使用位图表示,不再操作对象头,这样与写时复制兼容,并且标记与清除效率更高。

这种朴素的标记法,在标记阶段必须全局暂停,为了可以并发,可以使用三色标记法。

压缩阶段具体实现

lisp2中的对象中的对象:在对象头中有一个forwarding指针,指向将来该对象的位置。

lisp2中的对象

步骤:

compa
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值