sleep(0)for int/long
https://www.cnblogs.com/hongdada/p/16994326.html
JAVA并发-Thread.sleep(0)深入理解
https://www.cnblogs.com/thisiswhy/p/16657667.html
没有二十年功力,写不出Thread.sleep(0)这一行“看似无用”的代码!
- 在1000 ms之后,JVM尝试在Safepoint停止,以便Java线程进行定期清理,但是直到可数循环完成后才能执行此操作。
- 4.主线程的 Thread.sleep 方法从 native 返回,发现安全点操作正在进行中,于是把自己挂起,直到操作结束。
https://mp.weixin.qq.com/s/KDUccdLALWdjNBrFjVR74Q
真是绝了!这段被JVM动了手脚的代码!
https://juejin.cn/post/6844903878765314061
HBase实战:记一次Safepoint导致长时间STW的踩坑之旅
-
-XX:+SafepointTimeout
-
-XX:SafepointTimeoutDelay=2000
这两个参数的意思是当有线程进入Safepoint超过2000毫秒时,会认为进入Safepoint超时了,这时会打出来哪些线程没有进入Safepoint,具体日志如下:
最终查明导致这个问题是 HBase 中一个连接超时清理的函数,由于集群会有多个 MapReduce 或 Spark 任务进行访问,而每个任务又会同时起多个 Mapper/Reducer/Executer,其每一个都会作为一个 HBase 的客户端,这就导致了同时连接的数量会非常多。
更为关键的是,清理连接的索引值就是 int 类型,所以这是一个可数循环,HotSpot不会在循环中插入安全点。

import java.util.concurrent.atomic.AtomicInteger;
public class Safe {
public static AtomicInteger num = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
Runnable runnable = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000000000; i++) {
run0();
}
System.out.println("done");
}
private void run0() { 【重点,非native函数,仍然进不了安全点】
num.getAndAdd(1);
}
};
Thread t1 = new Thread(runnable);
Thread t2 = new Thread(runnable);
t1.start();
t2.start();
Thread.sleep(1000);
System.out.println("deng");
}
}
函数调用-----》 安全点?
必须native函数调用
https://zhuanlan.zhihu.com/p/286110609
jvm大局观之内存管理篇: 理解jvm安全点,写出更高效的代码
对于:"原因2正是示例程序会停顿超过额定1s至5s的直接原因"这个结论不认同,触发所有线程到安全点挂起的方法是safepoint.cpp的begin,该方法只在VMThread.cpp中只有loop方法中有调用,调用分为三种情况 等待vm操作过程中、执行vm操作过程中、周期性调用,使用vm参数-XX:+PrintSafepointStatistics等待1分钟停止程序,可以发现线程3还未启动之前,就有一个vmop为no vm operation耗时5秒,因此造成事例程序停顿5秒的主要原因是周期性调用才对
https://www.zhihu.com/question/29268019/answer/43762165
现代JVM中的Safe Region和Safe Point到底是如何定义和划分的?
浙公网安备 33010602011771号