1. 枚举根节点
可达性分析在执行GC的时候会停顿一下,如果引用关系不断变换的时候很难进行准确的可达性分析。目前虚拟机主要采用的是准确性GC,虚拟机应该有办法知道哪些地方存着对象引用,在HotSpot的实现中,用一组叫做OopMap的数据结构来实现这个目的,在类加载完成后记录下对象内的数据类型与偏移量,在JIT编译 过程中记录下栈和寄存器中哪些位置是引⽤。
2. 安全点
导致OopMap变化的指令非常多,我们只在特定的地点做记录,我们把这些点叫做安全点,也就是说让所以线程(不包括JNI调用的线程)跑到最近的安全点再停顿下来,所以安全点不能让GC等待时间过长,也不能太频繁。这里我们分为两种方式
- 抢占式中断,在GC的时候停下所以线程,再让没有到安全点的跑到安全点,目前几乎没有虚拟机采用这种方式进行GC
- 主动式中断,当GC需要中断线程的时候,在安全点上设置中断标 志,线程执⾏时主动轮询中断标志,发现标志为真时则主动中断挂 起线程。轮训标志的地方和安全点重合。
3.安全区域
指线程在某⼀段代码⽚段中,引⽤关系不会发⽣变化,在这个 区域中的任意点开始GC都是安全的。GC的时候不用考虑处于安全区域的,当线程出安全区域的时候要检查是否GC完成了,在线程处于blocked或sleep状态⽆法跑到安全点时,采⽤安全区域可以避免GC⻓时间等待。