一.根节点枚举
1.收集器在根节点枚举这一步骤时都是必须暂停用户线程的,现在可达性分析算法耗时最长的查找引用链的过程已经可以做到与用户线程一起并发。
2.根节点枚举始终还是必须在一个能保障一致性的快照中才得以进行——这里“一致性”的意思是整个枚举期间执行子系统看起来就像被冻结在某个时间点上,不会出现分析过程中,根节点集合的对象引用关系还在不断变化的情况,若这点不能满足的话,分析结果准确性也就无法保证。
3.在HotSpot的解决方案里,是使用一组称为OopMap的数据结构来达到2这个目的。
4.实际上HotSpot也的确没有为每条指令都生成OopMap,只是在“特定的位置”记录了这些信息,这些位置被称为安全点(Safepoint).(是以“是否具有让程序长时间执行的特征”为标准进行选定)
5.现在几乎没有虚拟机实现采用抢先式中断来暂停线程响应GC事件。(采用主动式中断)
6主动式中断的思想是当垃圾收集需要中断线程的时候,不直接对线程操作,仅仅简单地设置一个标志位,各个线程执行过程时会不停地主动去轮询这个标志,一旦发现中断标志为真时就自己在最近的安全点上主动中断挂起。
7HotSpot使用内存保护陷阱的方式,把轮询操作精简至只有一条汇编指令的程度。
8安全区域是指能够确保在某一段代码片段之中,引用关系不会发生变化,因此,在这个区域中任意地方开始垃圾收集都是安全的。(典型的场景便是用户线程处于Sleep状态或者Blocked状态)
二.记忆集
1。记忆集是一种用于记录从非收集区域指向收集区域的指针集合的抽象数据结构。
2。卡表就是记忆集的一种具体实现,它定义了记忆集的记录精度、与堆内存的映射关系等。卡表最简单的形式可以只是一个字节数组],而HotSpot虚拟机确实也是这样做的。
3。卡页大小都是以2的N次幂的字节数,通过代码可以看出HotSpot中使用的卡页是2的9次幂,即512字节(地址右移9位,相当于用地址除以512)。
4。一个卡页的内存中通常包含不止一个对象,只要卡页内有一个(或更多)对象的字段存在着跨代指针,那就将对应卡表的数组元素的值标识为1,称为这个元素变脏(Dirty),没有则标识为0。
5。HotSpot虚拟机里是通过写屏障(Write Barrier)技术维护卡表状态
6。为了避免伪共享问题,一种简单的解决方案是不采用无条件的写屏障,而是先检查卡表标记,只有当该卡表元素未被标记过时才将其标记为变脏.开启卡表会增加一次额外判断的开销,
三.可达性分析
三色标记
·白色:表示对象尚未被垃圾收集器访问过。显然在可达性分析刚刚开始的阶段,所有的对象都是 白色的,若在分析结束的阶段,仍然是白色的对象,即代表不可达。
·黑色:表示对象已经被垃圾收集器访问过,且这个对象的所有引用都已经扫描过。黑色的对象代 表已经扫描过,它是安全存活的,如果有其他对象引用指向了黑色对象,无须重新扫描一遍。黑色对 象不可能直接(不经过灰色对象)指向某个白色对象。
· 灰色:表示对象已经被垃圾收集器访问过,但这个对象上至少存在一个引用还没有被扫描过。
对象消失判定:
·赋值器插入了一条或多条从黑色对象到白色对象的新引用;
· 赋值器删除了全部从灰色对象到该白色对象的直接或间接引用
解决并发扫描时的对象消失问题,只需破坏这两个条件的任意一个即可。由此分别
产生了两种解决方案:增量更新和原始快照
本文介绍了垃圾收集器在根节点枚举时如何保证一致性,以及HotSpot虚拟机如何利用OopMap和安全点实现并发中断。同时,讨论了记忆集在记录跨代指针中的作用,特别是卡表的实现和写屏障技术的应用。此外,还阐述了可达性分析中的三色标记法及其并发问题的解决方案。
652

被折叠的 条评论
为什么被折叠?



