1 问题背景

遇到一个面试题“垃圾收集器”,其中涉及到了safepoint安全点,所以今天了解一下safepoint安全点

参考自:GCRoot与safePoint此笔记仅供自己参考,如有错误请指正

2 为什么会有safePoint

GC Root包括以下对象:

  • 虚拟机栈中引用的对象
  • 方法区中类属性引用的对象
  • 方法区中常量池引用的对象
  • 本地方法栈JNI引用的对象

这一过程称为根节点枚举,即垃圾回收的标记过程。所有的垃圾收集器在标记阶段都需要停止所有Java执行线程(即stop the world),以保证对象的引用状态不会改变

HotSpot虚拟机作为准确式虚拟机,维护了一个专门的映射表(OopMap)来记录哪些位置存放了对象的引用,来快速完成根节点枚举过程。

为每一个操作记录OopMap不现实(即jvm指令后面添加OopMap,会耗费大量的空间),HotSpot虚拟机引入了safePoint

3 safePoint是什么

safePoint是程序中的某些位置。线程执行到这些位置,此时线程的某些状态信息是可以确定的,在safePoint可以记录OopMap信息,线程在safePoint停顿,虚拟机进行GC。

4 线程停顿的方式

分为2种:抢先式中断主动式中断

4.1 抢先式中断

虚拟机需要GC时,中断所有线程,让没有到达safePoint的线程继续执行至safePoint并中断

4.2 主动式中断

虚拟机不直接中断线程,而是在内存设置标志位,当线程检查到标志位被设置了,则运行至safePoint时主动中断

5 safePoint出现在哪些位置

safePoint一般出现在:

  • 循环体的结尾
  • 方法返回之前
  • 调用方法的call之后
  • 抛出异常的位置

这些位置保证线程不会长时间运行导致无法到达safePoint,避免其他线程都停顿等待本线程。

6 safeRegion

safePoint无法解决 未到达safePoint 并且 处于休眠或者等待状态的情况,这时需要引入safeRegion。

safeRegion是代码的一块区域或者线程状态,在safeRegion中线程执行与否无法影响对象引用的状态。线程进入safeRegion会给自己加标志,告诉虚拟机可以进行GC;线程准备离开时,safeRegion会询问虚拟机是否完成。

7 总结

上面对STW(stop the world)、OopMap、safePoint、safeRegion有了一定的了解,那么现在进行总结将它们串起来

  • 垃圾回收会判断对象是否存活,即采用可达性算法分析,这一过程也叫根节点枚举,也叫标记过程。为了防止在标记过程中对象引用的状态发生改变,所以会采取STW(stop the world),让所有线程都停止下来进行可达性分析。

  • 判断对象是否存活的时候需要扫描GC Root引用链,因此需要对这个扫描工作优化一下性能,即能快速扫描GC Root引用链,因此采用一个数据结构 OopMap 来记录对象引用的信息。

  • 在每一条jvm指令后面记录对象引用的信息(OopMap)显然会耗费大量的空间,因此准确式的HotSpot虚拟机引入类safePoint**。safePoint是程序中的某些位置,线程在这些位置上其某些线程状态是可以确定的,可以记录OopMap。因此线程运行到safePoint时,线程会停顿下来,虚拟机进行GC垃圾回收。

  • 但是safePoint无法解决 未到达safePoint并且处于休眠或者等待的情况,这时引入safeRegion。safeRegion是代码的一块区域或者线程状态,在safeRegion中线程执行与否不会影响对象引用的状态。线程进入safeRegion会给自己加标志,告诉虚拟机可以进行GC垃圾回收。线程准备离开时,会咨询虚拟机是否完成GC。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐