以 GC safe-point引入html
GC如何找到不可用的对象?编写代码的时候是能够知道对象不可用的,但对于程序来讲,须要必定的方式来知晓,可用方法好比:编译分析,引用计数,和对象是否可达java
mutator 含义:,通常GC执行完以后,才会恢复应用的运行,而在GC相关文献中,这里的应用就是mutatorgit
一个对象只要可以经过mutator触达,那么它就是“活”着的。若是Mutator栈的一个槽位包含了对象的引用,那么对象就是直接可触达。而从直接可达对象可触达的对象一定也是可达的,于是可达性分析,只须要找到直接可达的引用。github
直接可达的引用就是根引用,根引用的集合就是根的集合安全
mutator的上下文就包含了直接可达的数据,因此要获取对象根集合就是要找到mutator上下文中的对象引用,而mutator的上下文指的就是它的栈、它的寄存器文件以及一些线程上特定的数据函数
全局数据自己也是直接可达的线程
可达性分析为了确保能正确的决定对象是否存活,GC须要获取mutator 上下文的一致性快照,而后枚举全部的根对象。翻译
这里的一致性指的是 快照的抽取就像只在一个时间点发生,来避免丢失一些活着的对象code
一种简单的方式就是在跟引用的过程当中暂停全部的线程。当mutator暂停了它的执行时,只有将全部引用信息保存在其上下文中,才能枚举根的集合,这意味着,mutator须要可以告知那些栈的槽位有引用,那些寄存器持有引用。若是GC可以准确的获取上述引用信息,它就称做精准根集合枚举。htm
没法获取就是不精准的,如下只讲精准的
对于java来讲,JIT知晓全部的栈帧信息和寄存器的内容,当JIT编译一个方法时,对于每条指令,它均可以去保存根引用信息,保存意味着额外的存储空间,若是要存储全部的指令就显得花销太大,另外在真实的运行过程当中也只有少数指令才会成为暂停点,所以JIT只须要保存这些指令点的信息就够了。而真正有机会成为暂停点的地方就称做 safe-points,即可以安全的枚举根集合的暂停点
。
“A point in program where the state of execution is known by the VM”,即代码中VM可以准确知道执行状态的位置。
safe-point有多个种类
Hotspot中二者实如今一块儿,概念上没有直接联系,须要数据不同
当GC想要触发一次回收时,它会设置一个标志,mutator则周期性的去检查(poll)这个标志,若是检查到了,就会立马暂停,这里的检查点(poll points)也是安全点,由JIT负责把poll points放到合适的位置
polling point插入的主要原则是:
权衡下来只在必须和必要的地方加
可是有时候并非长时间的执行,而是长时间的空闲,好比 sleep、block,线程在执行其余的native函数,这些时候JVM没法掌控执行能力,也就没法响应GC事件。
不一样的JVM选用不一样的位置放置safepoint。
引用safe-region。safe-region是指代码快中没有用到会变异的部分,这样的代码块中,任何一个点均可以安全的枚举根。当进入到safe-region中时,mutator会设置一个准备标记,在离开safe-region区域以前,会检查GC是否已经完成了回收,若是没有,那么就暂停执行,若是有,就能够直接离开safe-region区域,不须要暂停mutator
代码的执行过程当中,若是须要执行某些操做,好比GC,deoptimize,等等,必须知道当前程序全部线程运行到的地方,是否可以刚好知足我执行对应操做,而不会对应用程序自己形成损害,这些可以正确执行操做的地方也就是safepoint/saferegion