GC算法详解一(标记清除算法)

GC算法(标记清除算法)

简介

标记清除算法就如他字面上的意思一样,对程序中的非活动对象进行标记,随后清楚。通过这两个阶段令不能利用的空间重新得到利用。

标记阶段:就是对堆上的对象进行遍历并在便利过程中对活动对象以及活动对象所能引用的对象进行活动状态标记。遍历阶段根据方式不同可以分为深度优先和广度优先,由于深度优先在内存的占用上比广度小,一般选择深度优先遍历。

清除阶段:这个阶段会对堆上的对象进行一次遍历(相较于标记阶段的深度优先更像遍历数组的模式)这期间会将非活动对象加入到空闲空间链表中作为空闲的块。这个阶段来说堆越大所耗费的时间也越长。

分配:在空闲空间链表中根据选择算法寻找合适的块分配空间并返回这个块的引用,如果找到的块过大就讲剩余的内存存回到空闲空间链表。

合并:根据分配阶段来看,标记清除算法的清除会带来许多的碎片化空间,一个简单的做法就是在清除阶段加入合并的操作(就是对地址是否相邻的一个if判断),对本就相邻的两个块区域合并为一个块。

优点

优点就是实现简单,且相对于其他算法来说,标记清除算法并没有复制移动等操作,这就导致标记清除算法可以很容易的和其他的GC算法相结合。

缺点

第一个问题就是碎片化的空间,虽然有合并但是对于地址本不相邻的块依然是各自独立的,这就导致有可能在分配过程中即便浪费了时间也找不到符合大小的块。

第二个问题就是分配的操作耗时很大,虽然这取决于分配算法(先到先得,最优,最差等)也有可能遍历到最后依旧没有结果,而复制或者压缩算法由于是一整个空间分配时就十分方便快速了。

第三个就是标记清除算法跟写时复制技术不兼容,写时复制技术简单来理解就是fork后两个进程公用一个页或者说是一个空间只有在写的时候会复制内容到副本在操作来防止进程间的信息不一致问题,而标记清除算法每一次GC都要对整个堆进行修改,这就导致可能存在大量的不必要的复制。

优化版

多个空闲链表

标记清除算法的分配是耗时的,主要耗时在寻找块的过程,那么就可以像hash一样将1字大小的块放在一个链表,2字大小的放在另外一个链表,以此类推直到我们所设定的一个峰值如100个字以上的都放在最后一个链表lists[101]中,这样就可以通过空间换时间的方法根据目标内容的大小快速寻找块了。

位图标记

在单纯的标记清除算法中,每个活动状态的字都存在对象头中,这样就导致遍历过程很慢,这样其实我们可以通过一个01位置来设置是否活动,通过这样一个01序列的位图来决定是否是活动对象。位操作会比单纯的遍历要快的多。

其实还有很多的优化版例如延迟清除和BIBOP法等等,但是根本的还是标记清除算法的思路是不会变的,总的看就是根据标记清除算法的各种缺点和特性进行改进。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值