Java JVM 1:垃圾收集算法 - 标记清除算法(伪代码实现与深入分析)

标记清除法顾名思义,标记了,然后清除。这样一来会有大量的内存碎片。虽然如此,不过也有一些垃圾回收器采用他,例如现在最流行的 CMS 垃圾回收器。

算法原理

《深入理解 Java 虚拟机》中写道:

首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。
这句话其实个人是比较怀疑的。因为一般来说是先标记出还在活动的对象,因为可以根据 GC roots 推出,而不是标记除需要回收的对象,因为个人感觉你一开始是不知道需要回收的对象的。

伪代码实现

这里主要还是参考《垃圾回收的算法与实现》:

标记阶段

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

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

标记还是比较简单的。也就是遍历每一个根节点,由于每个根节点是一个树,这个时候可以采用广度优先算法或者深度优先算法来遍历这棵树,标记出所有的节点。

清除阶段

sweep_phase(){
    sweeping = $heap_start
    while(sweeping < $heap_end){
        if(sweeping.mark == TRUE){
            sweeping.mark = FALSE
        } else {
            sweeping.next = $free_list
            $free_list = sweeping
        }
        sweeping += sweeping.size
    }
}

这里主要是为了把清除的内存标记到空闲链表中,用于下一次分配内存。

优缺点

内存碎片问题

消耗的时间

和复制算法差不多

标记的时候需要遍历 GC roots,标记出活动对象。
清除的时候需要遍历整个堆

最后

感觉标记清除法不太好,比如说有大量碎片,以及再分配内存的时候又要遍历空闲链表,那么为什么 CMS 垃圾收集器还要用这个呢?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值