赞
踩
本文系转载自以下文章:
RednaxelaFX对安全点的解释
作者:RednaxelaFX
JVM安全点介绍
作者:EZLippi
Java Safepoint 与Stop The World
作者:chenliang1223
转载仅为方便学习查看,一切权利属于原作者,本人只是做了整理和排版,如果带来不便请联系我删除。
本文主要是搜集网络上的好文来记录下安全点概念。看了 才发现自己是有多无知,还有很多东西都不清楚,需要多学习啊。
OpenJDK官方定义如下:
GC Root
已知并且所有堆对象的内容一致的点。总的来说,安全点就是指,当线程运行到这类位置时,堆对象状态是确定一致的,JVM可以安全地进行操作,如GC,偏向锁解除等。
本节摘自https://www.zhihu.com/question/29268019/answer/43762165,作者:RednaxelaFX
GC safepoint
需要知道在那个程序位置上,调用栈、寄存器等一些重要的数据区域里什么地方包含了GC管理的指针;
如果要触发一次GC,那么JVM里的所有Java线程都必须到达GC safepoint。
Deoptimization safepoint
需要知道在那个程序位置上,原本抽象概念上的JVM的执行状态(所有局部变量、临时变量、锁,等等)到底分配到了什么地方,是在栈帧?的具体某个slot还是在某个寄存器里,之类的。
如果要执行一次deoptimization
,那么需要执行deoptimization的线程要在到达deoptimization safepoint之后才可以开始deoptimize。HotSpot中,安全点位置主要在:
为什么把这些位置设置为jvm的安全点呢,主要目的就是避免程序长时间无法进入safepoint,比如JVM在做GC之前要等所有的应用线程进入到安全点后VM线程才能分派GC任务 ,如果有线程一直没有进入到安全点,就会导致GC时JVM停顿时间延长。比如写了一个超大的循环导致线程一直没有进入到安全点,GC前停顿了8秒。
本节摘自https://www.zhihu.com/question/29268019/answer/43762165,作者:RednaxelaFX
无论是哪种安全点,最简洁的定义是“A point in program where the state of execution is known by the VM”。不同JVM实现会选用不同的位置放置安全点。
以HotSpot VM为例,在解释器里每条字节码的边界都可以是一个安全点,因为HotSpot的解释器总是能很容易的找出完整的“state of execution”。
而在JIT编译的代码里,HotSpot会在所有方法的临返回之前,以及所有非counted loop的循环的回跳之前放置安全点。
HotSpot的JIT编译器不但会生成机器码,还会额外在每个安全点生成一些“调试符号信息”,以便VM能找到所需的“state of execution”。
之所以只在选定的位置放置安全点是因为:
还有一种情况是当某个线程在执行native函数的时候。此时该线程在执行JVM管理之外的代码,不能对JVM的执行状态做任何修改,因而JVM要进入安全点不需要关心它。所以也可以把正在执行native函数的线程看作“已经进入了安全点”,或者把这种情况叫做“在safe-region里”。JVM外部要对JVM执行状态做修改必须要通过JNI。所有能修改JVM执行状态的JNI函数在入口处都有安全点检查,一旦JVM已经发出通知说此时应该已经到达安全点,就会在这些检查的地方停下来把控制权交给JVM。
换一个JVM说,JRockit选择放置安全点的地方在方法的入口以及循环末尾回跳之前,跟HotSpot略为不同。
在HotSpot虚拟机中,安全点协议是主动协作的 。每一个用户线程在安全点上都会检测一个标志位,来决定自己是否暂停执行。
一个线程可以在SafePoint上,也可以不在SafePoint上。
一个线程在SafePoint时,它的状态可以安全地其他JVM线程所操作和观测;不在SafePoint时,就不能。
在SafePoint上不代表被阻塞(比如:JNI方法就可以在SafePoint上运行),但是被阻塞一定发生在SafePoint上。
当JVM决定达到一个全局的SafePoint(也叫做Stop the World
)时,JVM里面所有的线程都要在SafePoint上并且不能离开,直到JVM让线程允许为止。这对要求所有线程都要被良好的描述的操作(比如CG,代码反优化等等)非常有好处。
一些JVM可以持有一些私有的线程到SafePoint上而不需要全局的SafePoint,比如Zing
.
当你写一些非安全的代码的时候,你必须假设SafePoint有可能发生在任何两个字节码之间。
非安全代码的调用并不要求必须有安全点,但是他们可以包含一个或者多个安全点。
所有类型的JVM有一些效率非常高的技巧和去快速的穿过SafePoint,线程并不需要真正地进入SafePoint除非虚拟机指示线程这么做。
所有的JNI方法都在SafePoint上执行。在安全点,JNI代码都不能改变和观测发起调用JNI代码线程的java机器状态。任何通过JNI API改变和观测调用线程的状态必须在调用线程离开安全点之后,以及再次进入SafePoint之前的时间内发生。
Hotspot GC研究- GC安全点 (Safepoint&Stop The World)
GC safe-point (or safepoint) and safe-region
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。