Thread.sleep(0)的作用

Thread.sleep(0)的作用 - Zach Web(๑`・ᴗ・´๑) (chinazach.com)

Thread.sleep(0)可以让线程进入 Safepoint,从而触发GC。

Safepoint

有了安全点的设定,也就决定了用户程序执行时并非在代码指令流的任意位置都能够停顿下来开始垃圾收集,而是强制要求必须执行到达安全点后才能够暂停。

换言之:没有到安全点,是不能 STW,从而进行 GC 的。

意思就是在可数循环(Counted Loop)的情况下,HotSpot 虚拟机搞了一个优化,就是等循环结束之后,线程才会进入安全点。

反过来说就是:循环如果没有结束,线程不会进入安全点,GC 线程就得等着当前的线程循环结束,进入安全点,才能开始工作。

Counted Loop(可数循环)

JVM认为比较短的循环,所以不会放置Safepoint,比如用int作为index的循环。与其对应的是Uncounted loop。

Uncounted loop

JVM会在每次循环回跳之前放置Safepoint,比如用long作为index的循环。所以一个常见的问题是当某个线程跑进了Counted loop时,JVM启动了GC,然后需要等待这个线程把循环跑完才能进入Safepoint,如果这个循环是个大循环,且循环内执行的比较慢,而且不存在其他函数调用产生其他Safepoint,这时就需要等待该线程跑完循环才能从其他位置进入Safepoint,这就导致了其他线程可能会长时间的STW。

Thread.sleep(0)
sleep 方法是一个 native 方法。一个线程在运行 native 方法后,返回到 Java 线程后,必须进行一次 safepoint 的检测。

native方法
当某线程在执行native函数是,这是JVM管理之外的代码,不能对JVM的执行状态做任何修改,因而JVM要进入safepoint不需要关心它,即正在执行 native 函数的线程看作“已经进入了 safepoint”,或者把这种情况叫做“在 safe-region 里”。

结论

调用 Thread.sleep(0)的目的是让线程进入 Safepoint。若是在场循环里面可以用long代替int,即Uncounted loop代替Counted Loop。

补充:STW

Stop-The-World: 是在垃圾回收算法执⾏过程当中,将JVM内存冻结、应用程序停顿的⼀种状态。

在STW 状态下,JAVA的所有线程都是停⽌执⾏的 -> GC线程除外
一旦Stop-the-world发生,除了GC所需的线程外,其他线程都将停止工作,中断了的线程直到GC任务结束才继续它们的任务。
STW是不可避免的,垃圾回收算法执⾏一定会出现STW,我们要做的只是减少停顿的时间
GC各种算法优化的重点,就是减少STW(暂停),同时这也是JVM调优的重点。
HotSpot 虚拟机为了避免安全点过多带来过重的负担,对循环还有一项优化措施,认为循环次数较少的话,执行时间应该也不会太长,所以使用 int 类型或范围更小的数据类型作为索引值的循环默认是不会被放置安全点的。这种循环被称为可数循环(Counted Loop),相对应地,使用 long 或者范围更大的数据类型作为索引值的循环就被称为不可数循环(Uncounted Loop),将会被放置安全点。

posted @   CharyGao  阅读(130)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示