一、什么是安全点:
在可达性分析算法中查找存活的对象,首先要找到哪些是GC Roots;
有两种查找GC Roots的方法:
一种是遍历方法区和栈区来查找(保守式GC);
一种是通过OopMap的数据结构来记录引用的位置(准确式GC),如在类加载过程中,JIT编译过程中,分别记录下 类成员 和 调用栈 中的引用的调用信息。对应OopMap的位置即可作用一个安全点。线程只有到达安全点时才能暂停下来进行可达性分析。
OopMap:你可以把oopMap简单理解成是调试信息。
在源代码里面每个变量都是有类型的,但是编译之后的代码就只有变量在栈上的位置了。
oopMap就是一个附加的信息,告诉你栈上哪个位置本来是个什么东西。这个信息是在jit编译时跟机器码一起产生的。因为只有编译器知道源代码跟产生的代码的对应关系。
每个方法可能会有好几个oopMap,就是根据safepoint把一个方法的代码分成几段,每一段代码一个oopMap,作用域自然也仅限于这一段代码。循环中引用多个对象,肯定会有多个变量,编译后占据栈上的多个位置。那这段代码的oopMap就包含多条记录咯
二、如何在GC发生时,所有线程都跑到最近的安全点上再停顿下来。有两种方法:
1. 抢先式中断:先把所有线程中数,判断是否在安全点,不是再放行,到安全点再停下来。
2. 主动式中断:不直接对线程操作,使用标志信息,各个线程论询这个标志,发现标志为真是就挂起。轮询标志的地方和安全点是重合的。
三、SafeRegion 安全区域:
Safepoint是对正在执行的线程设定的,如果一个线程当前没有使用CPU时(典型的如Sleep或中断),它就不能响应JVM的中断请求,再运行到安全点去。
Safepoint是指一段代码中,引用关系不会再发生变化,在这个区域中任何地方开始GC都是安全的。
按书上意思是,挂起的线程一定是在安全区域中了?