在HotSpot虚拟机上实现这些算法时,必须对算法的执行效率有严格的考量,才能保证虚拟机高效运行。
一、枚举根节点(Stop the World停顿,准确式GC,OOPMap)
1、从可达性分析算法中从GC Roots节点找引用链这个操作为例,可作为GC Roots的节点主要在【全局性引用(例如常量或类静态属性)】与【执行上下文(例如栈帧中的局部变量表)】中
2、现在很多应用仅仅方法区就有数百兆,如果要逐个检查这里面的引用,必然会消耗很多时间。
3、可达性分析对执行时间的敏感还体现在【GC停顿】上,因为这项分析工作必须在一个能确保【一致性】的【快照】中进行。
这里的"一致性"的意思是指:
在整个【分析期间】整个【执行系统】看起来就像被冻结在某个时间点上,
不可以出现分析过程中【对象引用】关系还在不断变化的情况,
该点不满足的话【分析结果】【准确性】就无法得到保证
这点是导致【GC】进行时必须【停顿】所有【Java执行线程】("Stop The World")的其中一个重要原因
即使是在号称(几乎)不会发生停顿的CMS收集器中,【枚举根节点】时也是必须要【停顿】的
4、现在主流的Java虚拟机使用【准确式GC】, 所以当执行系统停顿下来后,并不需要一个不漏的检查完所有【执行上下文】和【全局引用】的位置
虚拟机应当是有办法直接知道哪些地方存放着【对象引用】
在HotSpot的实现中,使用一组称为【oopMap】的数据结构来达到这个目的
在【类加载】完成时候,HotSpot就把【对象】内什么【偏移量】上是什么【类型的数据】计算出来
在【JIT编译】过程中,也会在特定的位置记录下【栈】和【寄存器】中哪些位置是【引用】
这样,【GC】在扫描时就可以直接得知这些信息了
二、安全点(只有到达安全点才可以停顿,开始GC)
1、在【OopMap】的协助下,【HotSpot】可以【快速】且【准确】的完成【GC Roots枚举】
2、实际上,HotSpot没有为【每条指令】都生成【OopMap】,只是在"特定的位置"记录了这些信息,这些位置称为【安全点】(Safe Point)
即【程序执行】时并非在所有地方都能停顿下来开始GC,只有在到达【安全点】时才能【暂停】
3、Safe Point的选择定即不能太少以致于让【GC】等待时间太长
也不能过于频繁以致于过分增大运行时的负荷
4、所以,【安全点】的选定基本上是以程序"是否具有让程序长时间执行的特征"为标准进行选定的
因为每条指令执行的时间都非常短暂,程序不太可能因为指令流长度太长这个原因而过长时间运行
"长时间执行"的最明显特征就是【指令序列复用】,例如:方法调用、循环跳转、异常跳转等。
所以,具有这些功能的【指令】才会产生安全点(Safe Point)
5、对于Safe Point,还有一个问题是:
如何在【GC】发生时让【所有线程(这里不包括执行JNI调用的线程)】都"跑"到最近的【安全点】上再停顿下来。
1、抢先式中断
不需要【线程】的执行代码主动去配合,在GC发生时,首先把【所有线程】【全部中断】
如果发现有线程中断的地方不在【安全点】上,就恢复线程,让它"跑"到【安全点】上
现在几乎没有虚拟机实现采用抢先式中断来【暂停线程】从而响应GC事件。
2、主动式中断
【主动式中断】思想是:
当GC需要中断线程的时候,不直接对线程操作,仅仅简单地设置一个标志,各个线程执行时主动去轮询这个标志,发现中断标志为真时就自己 中断挂起。
【轮询标志】的地方和安全点是重合的,另外再加上创建对象需要分配内存的地方。
三、安全区域
1、使用【SafePoint】似乎已经完美解决了【如何进入GC】的问题,但实际情况却不一定
【SafePoint】机制保证了程序执行时,在不太长的时间内就会遇到可进入GC的SafePoint。
2、但是,程序"不执行"的时候,所谓的【程序不执行】就是【没有分配CPU时间】,典型的例子就是:
线程处于Sleep状态或Blocked状态,这时候线程无法响应JVM的中断请求,"走"到安全的地方去中断挂起,JVM显然不太可能等待线程重新被分 配CPU时间。
3、对于这种情况,就需要【安全区域(Safe Region)】来解决
【安全区域】是指:
在一段代码片段之中,【引用关系】不会发生变化。
在这个区域中的任意地方开始GC都是安全的。
我们也可以把【Safe Region】看做是被扩展了的【Safe Point】
4、线程执行到【Safe Region】中的代码时,首先【标识】自己已经进入了【Safe Region】,
当在这段时间里JVM要发起GC时,就不用管标识自己为【Safe Region】状态的线程了。
5、线程要离开【Safe Region】时,它要检查系统是否已经完成了【根节点枚举】(或是整个GC过程)
如果完成了,那线程就继续执行
否则它就必须等待直到收到可以安全离开【Safe Region】的信号为止。