一文讲清楚 JVM Safe Point


一文讲清楚 JVM Safe Point

文章插图
大家好,我是树哥 。
关于 Safe Point 是 JVM 中很关键的一个概念,但我估计有不少同学不是很懂 。于是今天跟大家来深入聊聊 Safe Point , 希望通过这篇文章能解答这样几个问题:
  1. 什么是 Safe Point?
  2. 为啥需要 Safe Point?
  3. Safe Point 与 Stop the World 的关系?
什么是 Safe Point正如 Safe Point 名称的寓意一样,Safe Point 是一个线程可以安全停留在这里的代码点 。当我们需要进行 GC 操作的时候,JVM 可以让所有线程在 Safe Point 处停留下来,等到所有线程都停在 Safe Point 处时,就可以进行内存引用分析,从而确定哪些对象是存活的、哪些对象是不存活的 。
为什么让大家更加场景化地理解 Safe Point 这个概念,可以设想如下场景:
  1. 当需要 GC 时,需要知道哪些对象还被使用 , 或者已经不被使用可以回收了,这样就需要每个线程的对象使用情况 。
  2. 对于偏向锁(Biased Lock),在高并发时想要解除偏置,需要线程状态还有获取锁的线程的精确信息 。
  3. 对方法进行即时编译优化(OSR 栈上替换),或者反优化(bailout 栈上反优化) , 这需要线程究竟运行到方法的哪里的信息 。
【一文讲清楚 JVM Safe Point】对于上面这些操作,都需要知道现场的各种信息,例如寄存器有什么内容,堆使用情况等等 。在做这些操作的时候,线程需要暂停,等到这些操作完成才行,否则会有并发问题,这就需要 Safe Point 的存在 。
因此,我们可以将 Safe Point 理解成代码执行过程中的一些特殊位置,当线程执行到这个位置时 , 线程可以暂停 。Safe Point 处保存了其他位置没有的一些当前线程信息 , 可以提供给其他线程读?。庑┬畔ǎ合叱躺舷挛男畔? ,对象的内部指针等 。
而 Stop the World 就是所有线程同时进入 Safe Point 并停留在那里 , 等待 JVM 进行内存分析扫描,接着进行内存垃圾回收的时间 。
为啥需要 Safe Point前面我们说到,Safe Point 其实就是一个代码的特殊位置 , 在这个位置时线程可以暂停下来 。而当我们进行 GC 的时候,所有线程都要进入到 Safe Point 处,才可以进行内存的分析及垃圾回收 。根据这个过程,其实我们可以看到:Safe Point 其实就是栅栏的作用,让所有线程停下来 , 否则如果所有线程都在运行的话,JVM 无法进行对象引用的分析 , 那么也无法进行垃圾回收了 。
此外,另一个重要的 Java 线程特性 —— interrupted 也是根据 Safe Point 实现的 。当我们在代码里写入 Thread.interrupt() 时 , 只有线程运行到 Safe Point 处时才知道是否发生了 interrupted 。因此,Safe Point 也承担了存储线程通信的功能 。
总结简单地说 , Safe Point 就是人为规定出的一些代码位置,在这些位置上线程可以暂停下来,从而让 JVM 可以进行内存对象引用分析等操作 。此外,Safe Point 处也会存储一些特殊的信息,从而支持 Java 的某些特性,例如:Java 的 interrupt 特性需要到 Safe Point 处才能知道 。
其实关于 Safe Point 的内容还有不少,例如:
  1. 什么地方会放 Safe Point?
  2. Safe Point 具体是怎么实现的?
  3. 什么情况会让所有线程进入 Safe Point?
但对于大多数应用开发人员来说,其实暂时不需要了解得这么深,只需要知道啥是 Safe Point 以及其存在的价值即可 。如果你对这些问题感兴趣,可以通过参考资料部分详细了解 。
参考资料
  • JVM 相关 - SafePoint 与 Stop The World 全解 - 知乎
  • JVM源码分析之安全点safepoint - 简书

    推荐阅读