关于STW与SafePoint

什么是STW?

STW(stop-the-world)英文直译就是停止全世界,前面笔者有说过垃圾回收器必然会产生

在垃圾回收器通过GCRoots查找对应有用的对象的时候 ,如果不停止其他工作线程 可能会在搜索过程中对象引用发生改变或者GCRoots本身发生改变导致最后定位的数据不准确或者错误。目前所有的垃圾回收器都会产生STW

比如我们所说的CMS并发垃圾回收器和现在JDK默认的G1垃圾回收器,在第一步标记GCRoots的时候和Final Mark会产生STW

Safe Point

STW是一个概念,那么具体让工作线程暂停是如何做到的? JVM在执行我们代码的时候 会设置安全点主要是在 循环,方法调用,异常触发等的几个位置添加安全点

举个列子:
比如我们开车在经过红绿灯的时候,我们会事先查看下是否是绿灯如果是绿灯则通行,如果是红灯就等着,当红灯变成绿灯在通行

同理JVM设置的安全点就是在各个”路口“设置安全点,当程序执行到对应路口的时候 去查看下当前是否需要执行GC,如果需要GC 那么就在原地等待

image.png

如果安全点太多,显而易见,如果我们开车 隔个1米2米就很多红绿灯路口 那么我们通行的效率就会大大降低 ,相反如果红绿灯太少 那么行人过马路可能就比较麻烦了 (这只是一个比喻)

当我们程序执行过程中太多的安全点 那么会导致资源的消耗,每次到安全点都要去查询下GC是否需要运行,如果安全点太少,那么GC线程等待的时间就会变得很长 GC效率就会变低

Safe Region

安全区, 有了安全点为什么还需要安全区呢?

因为我们有些线程可能在执行的时候被会有几个状态,其中BLOCKTIME_WAIT或者WAIT的时候,如果在这几个状态 我们还需要等待线程到安全点的话可能需要很长时间或者很久的时间

所以就设计了安全区域,安全区域指的是在某一块代码内不会出现对象引用变更

比如线程在睡眠等压根就不执行,就像我们开车在高速上进入了服务区休息一样的道理,在这个区域内GC线程就不需要等待程序线程跑到安全点去查询了