如何安全的让所有用户线程Stop The World之使用安全点和安全区域

安全点

我们都知道GC在工作过程中,有时不得不进行STW(暂停所有用户线程)。但是要确保用户线程暂停的这行字节码是不会导致引用关系发生变化的。所以JVM会在字节码指令中,选出一些指令作为”安全点”,比如方法调用,循环跳转,异常跳转等,才会产生安全点。

为什么叫安全点呢?GC是要暂停业务线程。而业务线程可能是超多线程,他们肯定都要达到自己的Safepoint处才能完成所谓的Stop the world。这里我们有两种方法区实现。

1. 抢占式中断:当用户线程发现GC需要STW时,直接立刻停下。看看自己是不是听到Safepoint上。如果不在,再恢复线程到达最近的安全点。(好家伙,这随机能停到安全点的概率都能去买彩票了)。现在虚拟机已经不用这个方法了。

2. 主动式中断:当要发生GC时,设置一个标志位。然后其他线程运行到安全点时,都判断一下是否需要GC,如果需要就停止,否则继续执行。(明显靠谱很多)。

安全区域

为什么叫安全区域?

要是业务线程不执行(Sleep或Blocked状态),那么程序就没办法进入安全点,对于这种情况,就必须引入安全区域。

安全区域是指能够确保在某一段代码之中,引用关系不会发生变化。因此在这个区域总任意位置开始垃圾回收都是安全的。可以把安全区域看做拉长的安全点。如果sleep结束,GC还没结束,那么用户线程会变成安全点继续等待。

猜你喜欢

转载自blog.csdn.net/weixin_47184173/article/details/113628557