safepoint 是什么
java 程序外面有很多很多的 java 线程,每个 java 线程又有本人的 stack,并且共享了 heap。这些线程始终运行呀运行,一直对 stack 和 heap 进行操作。
这个时候如果 JVM 须要对 stack 和 heap 做一些操作该怎么办呢?
比方 JVM 要进行 GC 操作,或者要做 heap dump 等等,这时候如果线程都在对 stack 或者 heap 进行批改,那么将不是一个稳固的状态。GC 间接在这种状况下操作 stack 或者 heap,会导致线程的异样。
怎么解决呢?
这个时候 safepoint 就出场了。
safepoint 就是一个平安点,所有的线程执行到平安点的时候就会去查看是否须要执行 safepoint 操作,如果须要执行,那么所有的线程都将会期待,直到所有的线程进入 safepoint。
而后 JVM 执行相应的操作之后,所有的线程再复原执行。
safepoint 的例子
咱们举个例子,个别 safepoint 比方容易呈现在循环遍历的状况,还是应用咱们之前做 null 测试用的例子:
public class TestNull {public static void main(String[] args) throws InterruptedException {List<String> list= new ArrayList();
list.add("www.flydean.com");
for (int i = 0; i < 10000; i++)
{testMethod(list);
}
Thread.sleep(1000);
}
private static void testMethod(List<String> list)
{list.get(0);
}
}
运行后果如下:
标红的就是传说中的 safepoint。
线程什么时候会进入 safepoint
那么线程什么时候会进入 safepoint 呢?
一般来说,如果线程在竞争锁被阻塞,IO 被阻塞,或者在期待取得监视器锁状态时,线程就处于 safepoint 状态。
如果线程再执行 JNI 代码的哪一个时刻,java 线程也处于 safepoint 状态。因为 java 线程在执行本地代码之前,须要保留堆栈的状态,让后再移交给 native 办法。
如果 java 的字节码正在执行,那么咱们不能判断该线程是不是在 safepint 上。
safepoint 是怎么工作的
如果你应用的是 hotspot JVM,那么这个 safepoint 是一个全局的 safepoint,也就是说执行 Safepoint 须要暂停所有的线程。
如果你应用的是 Zing,那么能够在线程级别应用 safepoint。
咱们能够看到生成的汇编语言中 safepoint 其实是一个 test 命令。
test 指向的是一个非凡的内存页面地址,当 JVM 须要所有的线程都执行到 safepint 的时候,就会对该页面做一个标记。从而告诉所有的线程。
咱们再用一张图来具体阐明:
thread1 在收到设置 safepoint 之前是始终执行的,在收到信号之后还会执行一段时间,而后达到 Safepint 暂停执行。
thread2 先执行了一段时间,而后因为 CPU 被争夺,闲暇了一段时间,在这段时间外面,thread2 收到了设置 safepoint 的信号,而后 thread2 取得执行势力,接着继续执行,最初达到 safepoint。
thread3 是一个 native 办法,将会始终执行,晓得 safepoint 完结。
thread4 也是一个 native 办法,它和 thread3 的区别就在于,thread4 在 safepoint 开始和完结之间完结了,须要将控制器转交给一般的 java 线程,因为这个时候 JVM 在执行 Safepoint 的操作,所以任然须要暂停执行。
在 HotSpot VM 中,你能够在汇编语言中看到 safepoint 的两种模式:'{poll}’ 或者 ‘{poll return}’。
总结
本文具体的解说了 JVM 中 Safepoint 的作用,心愿大家可能喜爱。
本文作者:flydean 程序那些事
本文链接:http://www.flydean.com/jvm-safepoint2/
本文起源:flydean 的博客
欢送关注我的公众号: 程序那些事,更多精彩等着您!