大家好,我是树哥。

关于 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 处才能知道。

其实关于 Safe Point 的内容还有不少,例如:

  1. 什么地方会放 Safe Point?
  2. Safe Point 具体是怎么实现的?
  3. 什么情况会让所有线程进入 Safe Point?

但对于大多数应用开发人员来说,其实暂时不需要了解得这么深,只需要知道啥是 Safe Point 以及其存在的价值即可。如果你对这些问题感兴趣,可以通过参考资料部分详细了解。

参考资料

一文讲清楚 JVM Safe Point的更多相关文章

  1. 一文学会JVM性能优化

    实战性能优化 1 重新认知JVM 之前我们画过一张图,是从Class文件到类装载器,再到运行时数据区的过程,现在咱们把这张图不妨丰富完善一下,展示了JVM的大体物理结构图. 执行引擎:用于执行JVM字 ...

  2. 一文洞悉JVM内存管理机制

    前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 学习导图: 一.为什么要学习内存管理? Java与C++之间有一堵由内存动态分配和垃圾回收机制所围成的高墙,墙 ...

  3. 一文了解JVM全部垃圾回收器,从Serial到ZGC

    <对象搜索算法与回收算法>介绍了垃圾回收的基础算法,相当于垃圾回收的方法论.接下来就详细看看垃圾回收的具体实现. 上文提到过现代的商用虚拟机的都是采用分代收集的,不同的区域用不同的收集器. ...

  4. 一文了解JVM

    一.什么是JVM JVM是Java Virtual Machine(Java 虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实 ...

  5. 推荐收藏系列:一文理解JVM虚拟机(内存、垃圾回收、性能优化)解决面试中遇到问题(图解版)

    欢迎一起学习 <提升能力,涨薪可待篇> <面试知识,工作可待篇 > <实战演练,拒绝996篇 > 欢迎关注我博客 也欢迎关注公 众 号[Ccww笔记],原创技术文章 ...

  6. 一文学会JVM配置参数与工具使用

    经过前面的各种分析,我们知道了关于JVM很多的知识,比如版本信息,类加载,堆,方法区,垃圾回收等,但是总觉得心里不踏实,原因是没看到实际的一些东西. 所以这在本文,咱们就好好来聊一聊关于怎么将这些内容 ...

  7. 一文讲清楚MySQL事务隔离级别和实现原理,开发人员必备知识点

    经常提到数据库的事务,那你知道数据库还有事务隔离的说法吗,事务隔离还有隔离级别,那什么是事务隔离,隔离级别又是什么呢?本文就帮大家梳理一下. MySQL 事务 本文所说的 MySQL 事务都是指在 I ...

  8. 【Java】JMM内存模型和JVM内存结构

    JMM内存模型和JVM内存结构 JAVA内存模型(Java Memory Model) Java内存模型,一般指的是JDK 5 开始使用的新的内存模型,主要由JSR-133: JavaTM Memor ...

  9. 五分钟学Java:如何学习Java面试必考的JVM虚拟机

    原创声明 本文首发于微信公众号[程序员黄小斜] 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图 为什么要学习JVM虚拟机 最近的你有没有参加Java面试呢?你有没有发现,Java ...

随机推荐

  1. zabbix监控添加学习笔记

    在实际生产环境中,除了CPU.内存等一些系统信息可以挂载zabbix的自带模板Template OS Linux:但是一些公司开发的定制服务需要自己写模板或者监控项去监控: 一.监控公司的java服务 ...

  2. react 吸顶实现

    今天获取到一个需求,其实就是吸顶的需求,页面下滑,某一块dom隐藏时发生吸顶现象.这种特效其实老生常谈了,但是在这次做的时候,突发奇想,能否将其做成一个 hook ,从而实现出传递ref即可使得 do ...

  3. netdata检测工具的安装与使用

    Netdata 是一款 Linux 性能实时监测工具..以web的可视化方式展示系统及应用程序的实时运行状态(包括cpu.内存.硬盘输入/输出.网络等linux性能的数据). Netdata文档地址: ...

  4. 从RabbitMQ平滑迁移到RocketMQ技术实战

    作者:vivo 互联网中间件团队- Liu Runyun 大量业务使用消息中间件进行系统间的解耦.异步化.削峰填谷设计实现.公司内部前期基于RabbitMQ实现了一套高可用的消息中间件平台.随着业务的 ...

  5. Java学习 (四)基础篇 Java基础语法

    注释&标识符&关键字 注释 注释并不会被执行,其主要目的用于解释当前代码 书写注释是一个非常好的习惯,大厂要求之一 public class hello { public static ...

  6. 5.8 NOI 模拟

    \(T1\) 比较容易想到的 二分转化为判定,判定是否存在一个子图能保证能一直在\(x\)时间内到达\(n\) 设\(dis(u,v)\)表示\(u->v\)的最短路 先找出候选节点\(i,di ...

  7. mosquitto使用的基本流程以及一些遇见的问题

    改配置文件 以记事本的方式打开mosquitto.conf更改部分内容,找到# listener port-number [ip address/host name/unix socket path] ...

  8. ETCD快速入门-02 ETCD安装

    2.ETCD安装     etcd 安装可以通过源码构建也可以使用官方构建的二进制文件进行安装.我们以二进制文件为例,系统为CentOS 7.9,操作步骤如下所示: 2.1 Linux ETCD_VE ...

  9. 映射问题,命名空间不能为空:org.apache.ibatis.builder.BuilderException : Mapper's namesapce cannot be empty

    今天配置Spring配置文件时,出现了以下的报错 倒数第三行,意思是Mapper的namespace(命名空间)不能为空 检查xml文件里映射文件是否配置,如果没有配置,那请添加映射文件,不然Spri ...

  10. BZOJ3732 (Kruskal重构树)

    Kruskal重构树上\(x\)和\(v\)的\(lca\)的权值即为它们最长路最小值 #include <cstdio> #include <iostream> #inclu ...