Hotspot细节实现
3、安全区域
产生原因
安全点解决了如何解决线程停顿,让虚拟机进入垃圾回收状态问题。安全点机制保证了程序执行时,在不太长的时间内就会遇到可进入垃圾回收的状态
但是如果程序不执行呢?比如睡眠过程中 或者阻塞过程中,不执行的时候是不知道现在是垃圾回收,醒来突然发现垃圾回收了,就很尴尬了。如果等待醒来再去安全点集合,又回花很长时间去整理 一致 后再收集 这样的情况下是肯定不能被允许的
安全区域概念
能够保证某段代码片段中 引用关系不会发生变化,再这个区域中任意地方开始垃圾收集都是安全的,我们也可以把安全区域当作连续几个命令行操作的安全点
实现过程
首先,会标识自己已经进入安全区
然后:虚拟机发起垃圾收集的时候就不会去管这些已经声明自己在安全区域内的线程了
当线程离开安全区域的时候 要检查是否完成垃圾收集,如果完成若无其事的离开,要不等一会,知道危险信号解除为止
4、记忆集与卡表
产生原因:
分代收集理论的时候 为了解决对象跨代引用所带来的问题,垃圾收集器在新生代建立名为记忆集的数据结构,目的是为了避免把整个老年代加入GC ROOTs 扫描范围
只要是设计部分区域收集行为的垃圾收集器 典型比如G1 ZGC和ShenNandoah 收集器 都会有相同的问题
记忆集概念
记忆集是一种用于记录从非收集区域指向收集区域的指针集合的抽象数据结构
如果我们不考虑效率和成本的话 最简单的实现可以用非收集区域中所有含跨代引用的对象数组来实现这个数据机构
实现过程:
这种全部卡带引用的对象的实现方案 是把一个对象都放入到一个数组中进行添加,无论是空间占用还是维护成本都相当的高
记忆集的目的是收集器判断某一块非搜集区域是否存在指向收集区域的指针就可以了,并不需要了解这些跨代指针的全部细节
可供选择的记录精度:
字长精度:每个记录精确到一个机器字长 该字包含跨代指针
对象精度:每个记录精度到一个对象 该对象里面又字段含有的跨代指针
卡精度:每个记录到一块内存区域 该区域含有对象跨代指针
卡精度(卡表)
卡精度一般称其为卡表去实现记忆集,是目前最常用的一种记忆集实现形式
卡表是记忆集的一种具体实现 定义了记忆集的记录精度 与堆内存的映射关机
卡表的最简单的形式可以是字节数组,字节数组CARD-TABLE 每一个元素都对应着表示内存区域中一块特定大小的内存块
这个内存块被成为卡页 卡叶一般都是2的N次幂
成为卡页 卡叶一般都是2的N次幂
一个卡叶的内存中不止一个对象 只要卡页内又一个或者更多的对象字段存在跨代指针,那就对应的卡表数组元素标识为1,称这个元素变脏, 没有标识为0 当垃圾收集发生时,只要筛选出变脏的元素 就能轻易得出哪些元素包含跨代指针,加入GC ROOTs一并扫描