您的位置:首页 > 编程语言 > Java开发

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

2017-04-09 19:46 696 查看
标记清除法顾名思义,标记了,然后清除。这样一来会有大量的内存碎片。虽然如此,不过也有一些垃圾回收器采用他,例如现在最流行的 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 垃圾收集器还要用这个呢?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  虚拟机
相关文章推荐