一文讲清楚 JVM Safe Point

【一文讲清楚 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 栈上反优化) , 这需要线程究竟运行到方法的哪里的信息 。
对于上面这些操作 , 都需要知道现场的各种信息 , 例如寄存器有什么内容 , 堆使用情况等等 。在做这些操作的时候 , 线程需要暂停 , 等到这些操作完成才行 , 否则会有并发问题 , 这就需要 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 处才能知道 。

经验总结扩展阅读