技术编程|GC垃圾回收算法( 二 )


根据分配策略的不同可能会产生大量的小分块 。 但如果它们是连续的 , 我们就能把所有的小分块连在一起形成一个大分块 。 这种“连接连续分块”的操作就叫作合并(coalescing) , 合并是在清除阶段进行的 。 位图标记
只收集各个对象的标志位并表格化 , 不跟对象一起管理 。 在标记的时候 , 不在对象的头里置位 , 而是在这个表格中的特定场所置位 。 像这样集合了用于标记的位的表格称为“位图表格”(bitmap table) , 利用这个表格进行标记的行为称为“位图标记” 。 位图表格的实现方法有多种 , 例如散列表和树形结构和整数型数组等 。

技术编程|GC垃圾回收算法
本文插图

位图标记延迟清除法
清除操作所花费的时间是与堆大小成正比的 , 如果处理的堆越大 , 清除算法所花费的时间就越长 。
延迟清除法 , 在标记操作结束后 , 不一定会进行清除操作 , 会缩减mutator的暂停时间 。 标记清除算法的优缺点
?
优点:标记清除算法实现简单 , 与其他的的算法组合也就相对简单;
缺点:标记清楚算法不会移动对象 , 但容易产生碎片化的空间 , 造成内存浪费 。
?
如图:

技术编程|GC垃圾回收算法
本文插图

上图的「根」指的是「GC root」 , 通过「根可达算法」确认是不是垃圾 。 这里简单介绍下根可达算法的定义:从GC Root作为起点开始搜索 , 那么整个连通图中对象都是活的 , 对于GC Root无法达到的对象便是垃圾对象 , 随时可被GC回收 。
如果我需要3空间的内存 , 而2空间的内存就存不下 。 就会被空闲 , 造成内存浪费 。 引用计数法
引用计数法中引入了一个计数器 。 计数器表示的是对象的引用次数 。 如果对象引用次数为0 , 那么这个对象可以被清除 。 优缺点
「优点」:可即刻回收垃圾 , 空间不会被垃圾长久占用 。
「缺点」:计数器值的增减处理繁重 , 计数器也需要占用内存 。 无法回收循环引用 。 GC复制算法
简单来说 , GC复制算法就是把空间里的活动对象复制到其他空间 。 把原空间里的所有对象都回收掉 。 如图所示:

技术编程|GC垃圾回收算法
本文插图

当From空间被占满时 , GC将活动的对象全部复制到To空间 。 当复制完成后 , 该算法会将From空间和To空间互换 , GC结束 。。 From 空间和To 空间大小必须一致 。 这是为了保证能把From 空间中的所有活动对象都收纳到To 空间里 。 优缺点
优秀的吞吐量 , 可实现高速分配 , 不会发生碎片化 。
但是复制算法需要把堆进行二等分 , 只有一半的堆能被使用 。 造成堆的浪费 。 还有复制算法在复制某个对象时要递归复制它的对象 , 这里会带来额外的负担 , 有栈溢出的可能 。 GC标记压缩算法
此算法分为标记阶段和压缩阶段 , 标记阶段同上面几种算法的标记功能一样 , 我们来说说压缩阶段 , 分为3步骤:?设定forwarding 指针更新指针移动对象?
标记压缩实际上就是将活动的对象xi整理到一边 , 尽量的减少碎片化 , 来看看实际的效果:

技术编程|GC垃圾回收算法
本文插图

image-20200730141439426优缺点
可有效利用堆 , 但是压缩会有计算成本 。
GC主要的回收算法就介绍这么多了 , 其实际的算法很复杂 。 有兴趣的可以自行研究 。
「参考:」
《垃圾回收的算法与实现》 作者: 中村成洋 / 相川光


推荐阅读