一、枚举根节点
- 在可达性分析中使用常量或者静态变量作为根节点,但是在很多应用中,仅仅方法区就有数百兆,如果逐个检查会消耗很多时间
- GC停顿:在检查对象死亡时需要确保一致性,所以在整个分析期间,虚拟机必须停掉所有线程
- Hotspot使用了一种OopMap的数据结构,他可以知道哪些地方存放着哪些对象引用,不需要在GC停顿的时候进行遍历,节省时间
二、安全点
- OopMap可以很高效的完成GC Roots枚举,但是在实际应用过程中,导致OopMap结构变化的指令非常多,如果每次变化都产生新的OopMap,那么GC的空间成本将变得很高
- 所以Hotspot只在安全点(Safepoint)上进行暂停
- 安全点的选择遵循“是否具有让程序长时间执行的特征”,即方法调用、循环跳转、异常跳转的才会产生SafePoint
- 在GC发生时,如何让所有线程都在安全点上停顿下来呢,有两种方式,第一是抢先式中断,第二种是主动式中断
- 抢先式中断:就是当GC发生时,如果发现某一线程不在安全点上,则恢复线程让它跑到安全点上停下来
- 主动式中断:不直接对线程进行操作,设置一个标志,各个线程主动轮询这个标志,如果标志为真(发生GC)则线程暂停(Hotspot使用这种方式)
三、安全区域
- 安全点可以解决正在执行的线程在GC时停顿的一致性,那么如果是线程在Sleep状态,或者Blocked状态呢
- 这时引入安全区域(SafeRegion)的概念,在线程进入“不执行”状态时,标记自己进入Safe Region,这样在GC时,就不用管Safe Region的线程了
- 在线程要离开Safe Region时,需要检查系统是否已经完成根节点枚举或者整个GC过程,如果完成了,则线程继续执行,否则需要等到可以安全离开Safe Region为止