GC算法-标记整理

算法详解

标记/整理算法与标记/清除算法非常相似,它也是分为两个阶段:标记和整理。

标记:它的第一个阶段与标记/清除算法是一模一样的,均是遍历GC Roots,然后将存活的对象标记。

整理:移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收。
因此,第二阶段才称为整理阶段。

GC前内存中对象的状态与布局,如下图:

GC线程开始工作,那么紧接着开始的就是标记阶段了。此阶段与标记/清除算法的标记阶段是一样一样的,我们看标记阶段过后对象的状态,如下图: 

接下来,便应该是整理阶段了。当整理阶段处理完以后,内存的布局如下图:

可以看到,标记的存活对象将会被整理,按照内存地址依次排列,而未被标记的内存会被清理掉。如此一来,当我们需要给新对象分配内存时,JVM只需要持有一个内存的起始地址即可,这比维护一个空闲列表显然少了许多开销。 不难看出,标记/整理算法不仅弥补了标记/清除算法当中,内存区域分散的缺点,也消除了复制算法当中,内存减半的高额代价,可谓是一举两得。

算法缺点

标记/整理算法唯一的缺点就是效率不高,不仅要标记所有存活对象,还要整理所有存活对象的引用地址。从效率上来说,标记/整理算法要低于复制算法。

总结

相同点

标记清除、复制、标记整理算法,它们的共同点主要有以下两点:

1、三个算法都基于根搜索算法去判断一个对象是否应该被回收,而支撑根搜索算法可以正常工作的理论依据,就是语法中变量作用域的相关内容。因此,要想防止内存泄露,最根本的办法就是掌握好变量作用域。

2、在GC线程开启时,或者说GC过程开始时,它们都要暂停应用程序(stop the world)

性能比较

效率:

复制算法>标记/整理算法>标记/清除算法(此处的效率只是简单的对比时间复杂度,实际情况不一定如此)

内存整齐度:复制算法=标记/整理算法>标记/清除算法

内存利用率:标记/整理算法=标记/清除算法>复制算法

既然这三种算法都各有缺陷,高人们自然不会容许这种情况发生。因此,高人们提出可以根据对象的不同特性,使用不同的算法处理,于是奇迹发生了,高人们终于找到了GC算法中的神级算法—–分代搜集算法

0 0 投票数
Article Rating
订阅评论
提醒
guest
0 评论
最旧
最新 最多投票
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x