成都网站建设设计

将想法与焦点和您一起共享

SafePoint安全点是什么

这篇文章主要介绍“SafePoint安全点是什么”,在日常操作中,相信很多人在SafePoint安全点是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SafePoint安全点是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

创新互联公司专注于云州企业网站建设,成都响应式网站建设公司,商城建设。云州网站建设公司,为云州等地区提供建站服务。全流程按需规划网站,专业设计,全程项目跟踪,创新互联公司专业和态度为您提供的服务

前提概要

safepoint又称为安全点,它是hotspot等JVM中的一个重要概念。下面我们分部分了解下safepoint是什么、safepoint的作用、safepoint是如何实现的以及作为开发者有哪些需要注意的地方。

SafePoint安全点是什么

JVM的主要任务是执行Java程序,而JVM运行时本身也是一个程序,但是为了执行Java程序JVM还有不少辅助工作,比如进行GC、JIT编译等等。一般会把运行在JVM上的用户Java程序称为mutator

GC为例,JVM中一般的GC都使用可达性分析,也就是从应用程序的一些GC Root(比如运行中的线程栈里的方法栈帧中本地变量表、操作数表中的引用、静态变量引用等)开始通过引用进行引用图遍历,如果在JVM遍历的过程中mutator也在运行,则mutator则可能会修改这个对象图的引用关系,如果JVM不对这种并发修改进行特殊处理,可能导致一些非可回收对象没有被遍历到,从而被标记成垃圾对象而被错误的回收。(切记标记的都是存活的对象,而不是要被清除的,此外不会之遍历不到就会被立刻回收,还需要考虑finalize方法进行再一次判断)。

如果要完全并发GC,JVM的实现成本会比较大,并且很多情况下整体的吞吐量是会降低的。(联想下并发编程中cas原子操作和加锁的使用,如果竞争比较激烈使用加锁效率更高,因为能够减少cas循环的cpu消耗

因此在很多GC收集器中都会有一些StopTheWorld阶段,这个StopTheWorld就是safepoint。在safepoint中不会有mutator操作对象,并且线程栈和heap中每个位置的数据类型也是确定的(比如一个8bit的数据是long还是对象引用)。

一个线程要么在safepoint中,要么不在safepoint中。上面提到的StopTheWorld指的是全局safepoint(针对hotspot),也就是要求所有线程都处于safepoint状态。后面如果没有特别说明safepoint也指的是全局safepoint。

safepoint是如何实现的

JVM如何通知线程进入safepoint

在hotspot实现中safepoint是协作式的,当JVM需要mutator进入safepoint时,会设置一个状态标记表示要进入safepoint了每个mutator线程都会在合适的时机检查这个状态标记,如果发现需要进入safepoint则会暂停自己

这里的合适的时机的选取,既要不那么频繁,避免增大运行时开销(不能每走一步看一次),也不能太久不检查,避免进入safepoint进入太慢(需要线程们都进入safepoint状态才行,如果有一个线程一直干活不检查safepoint会影响其他线程,毕竟其他线程都在等着)。

  • 如果是compiled code(JIT编译后的代码),JIT会在某些地方插入检查代码,比如方法调用返回和循环跳回的地方

  • 如果是interpreted code(解释执行),JVM有两个字节码分发表,如果需要进入safepoint,则JVM会切换到有safepoint状态检查的那个分发表上

各个线程如何检查是否要进入safepoint

为了尽量减少开销,hotspot中safepoint的状态检查的实现方式是读取一个内存值,如果需要进入safepoint,则将这个内存页设置成被保护的,这样就会触发一个page fault,然后就可以通过异常处理进入safepoint了。这种方式比准确读取一个内存值(比如一个boolean数据)要轻量(因为需要内存同步)

大家可能会想到如果一个线程处于sleep,线程在执行JNI代码时也处于safepoint中,并且其他的”阻塞”状态也是在safepoint中,比如Thread.sleep,如果要退出线程要退出safepoint需要JVM允许,这样就不会出现sleep状态的线程在其他线程进入safepoint后突然运行这种情况了。

有哪些会引发safepoint的情况

除了一些GC阶段需要safepoint内执行,其他的比较常见的操作有。

revoke bias

(偏向锁撤销,频繁看到偏向锁撤销可以考虑关闭偏向锁-XX:-UseBiasedLocking)

dump线程栈

无论是通过jstack还是通过jmx的,ThreadMXBean.getThreadInfo(maxDepth>0的情况)还是Thread.getAllStackTraces等方法,都会触发safepoint,如果线程非常多则可能导致比较长时间的暂停。

class redefinition

(通过Instrument对象对类进行retransform或redefine)

code deoptimization

如何排查safepoint相关问题

在JVM启动参数上增加一些参数可以打印出应用暂停和safepoint相关信息。

如果版本<=jdk8

-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime 
-XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1

如果版本>jdk8

-Xlog:gc*=info::time,tags,tid 
-Xlog:safepoint=info::time,tags,tid

一个示例

[2020-05-18T09:18:55.978-0800][19459][safepoint    ] Application time: 1.0038747 seconds
[2020-05-18T09:18:55.978-0800][19459][safepoint    ] Entering safepoint region: ThreadDump
[2020-05-18T09:18:55.980-0800][19459][safepoint    ] Leaving safepoint region
[2020-05-18T09:18:55.980-0800][19459][safepoint    ] Total time for which application threads were stopped: 0.0017502 seconds, Stopping threads took: 0.0000312 seconds

这个表示应用线程运行了1.0038747秒后,因为ThreadDump开始进入safepoint,应用线程被暂停了0.0017502秒,暂停这些线程花了0.0000312秒

到此,关于“SafePoint安全点是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!


网站名称:SafePoint安全点是什么
转载注明:http://chengdu.cdxwcx.cn/article/jpjeoh.html