G1GC 算法读书笔记
G1GC 是什么
G1GC 中的实时性
G1GC 具有软实时性,具备以下两种功能:
设置期望暂停时间:用户自定义 GC 暂停(stop the world)时间,尽力保证不超过此时间
可预测性:预测下次 GC 暂停的时间。根据预测的结果,通过延迟 GC、拆分 GC 目标对象等手段来遵守设置的期望暂停时间。
堆结构
堆内部划分为大小相等的区域,排成一排。以区域为单位 GC。用户可以随意设置区域大小,内部会将用户设置的值向上调整为 2 的指数幂,并以该数作为区域的大小。
如果正在分配对象的某个区域已经满了,GC 线程会寻找下一个空闲区域继续分配。空闲区域通过链表进行管理,查找时间复杂度为 O(n)。
执行过程
并发标记:针对区域内所有存活的对象进行标记。
转移(整理):负责释放堆中死亡对象占用的内存空间。转移的同时起到了压缩作用,因此不会发生碎片化。
并发标记和转移
并发标记由并发标记线程执行,在尽量不暂停的情况下标记出存活对象。在并发标记结束之后记录下每个区域内存活对象的数量。
转移是将待回收区域内的存活对象复制到其他空闲区域,然后将待回收区域重置为空闲状态。
并发标记和转移在处理上是相互独立的。
并发标记
每个区域都有两个标记位图:next 和 prev,next 是本次标记位图,prev 是上次标记的标记位图。
执行步骤
初始标记阶段:暂停,标记可由根直接引用的对象
GC 线程先创建标记位图 next,所有区域的标记位图创建完成之后,开始根扫描。
并发标记阶段:1 中标记的对象所引用的对象。开启并发标记线程进行标记。
GC 线程和应用程序线程并发执行。为防止发生“标记遗漏”,必须使用写屏障技术记录对象间的引用关系变化。
SATB(初始快照)
将并发标记开始时对象间的引用关系,以逻辑快照的形式进行保存的手段。
最终标记阶段:扫描 2 中没有标记的对象。
暂停应用程序执行,扫描 SATB 本地队列中可能存在的待扫描对象。
存活对象计数:对所有被标记的对象进行计数。
扫描 next,统计区域内存活对象的字节数。
收尾工作:做收尾工作,并为下次标记做准备。
暂停应用程序执行,扫描每个区域,将标记位图 next 中并发标记结果移动到标记位图 prev 中,再对并发标记中使用过的标记值进行重置,为下次并发标记做准备。
对没有存活对象的区域进行回收。
计算每个区域的转移效率,并按照效率对区域进行降序排序。
转移效率
转移 1 个字节所需的时间:死亡对象的字节数/转移所需的时间。
死亡对象越多,转移效率越高。
转移
通过转移专用记忆集合来发现对象。通过卡表(card table)来实现转移专用记忆集合。
卡表(card table)
由元素大小为 1B 的数组实现的,卡表里的元素称为卡片,对应堆中大小适当的一段存储空间。
转移专用写屏障
版权声明: 本文为 InfoQ 作者【老猎人】的原创文章。
原文链接:【http://xie.infoq.cn/article/d10310d880822fcd837a521f5】。未经作者许可,禁止转载。
评论