JVM中的STW(Stop The World)

JVM中的STW(Stop The World)待更新

大家好,欢迎来到IT知识分享网。

1. STW是什么?

Stop一the一World,简称STW,指的是Gc事件发生过程中,会产生应用程序的停顿。停顿产生时整个应用程序线程都会被暂停,没有任何响应,有点像卡死的感觉,这个停顿称为STW。

2. STW出现的时机

  • 可达性分析算法中枚举根节点(GC Roots)会导致所有Java执行线程停顿。
  • 目前主流的虚拟机采用的都是可达性算法,算法的核心是利用根对象作为起始点,根据对象之间的引用关系,即引用链,通过遍历引用链来判断对象的是否存活。
  • 然而,可达性分析算法要求全过程都基于一个能保障一致性的快照中才能够进行分析,简单来说,就是必须全程冻结用户线程的运行。

3. 为什么必须冻结用户线程呢?

  • 因为,如果用户线程和垃圾回收线程并发执行,有可能会出现两个问题:浮动垃圾 和 对象消失,详情参考并发的可达性分析。

3.1 停顿的原因

3.2 什么是 SafePoint

3.3 SafePoint 在哪些位置

3.4 如何实现 STW/SafePoint

首先,Stop-The-World 需要所有的用户线程处于 SafePoint,这意味着某个用户线程运行到 SafePoint,其它用户线程可能处于不同的状态。 所有线程都到达GC Safepoint,有两种方法: ◉ 抢占式中断(Preemptive Suspension) JVM会中断所有线程,然后依次检查每个线程中断的位置是否为Safepoint,如果不是则恢复用户线程,让它执行至 Safepoint 再阻塞。 ◉ 主动式中断(Voluntary Suspension) 大部分 JVM 实现都是采用主动式中断,需要阻塞用户线程的时候,首先做一个标志,用户线程会主动轮询这个标志位,如果标志位处于就绪状态,就自行中断。 那么,针对用户线程的各种状态,需要怎么处理呢? 正在执行字节码 解释器检查当前用户线程的标志,VM 线程调用以下方法阻塞线程。 Interpreter::notice_safepoints() 正在运行 native 代码 如果 VM线程 发现一个当前用户线程正在执行 native 代码,不会等待线程阻塞。当线程从 native 代码返回时,检查 Safepoint 状态,如果处于 SafePoint,就直接阻塞线程。 正在运行 JIT 编译好的代码 设置 Poling Page 为不可读,当前用户线程发现该内存页不可读时,就会被阻塞。 Poling Page: 在 JVM 初始化启动的时候,初始化的一个单独的内存页面,这个页面是让运行的编译过的代码的线程进入阻塞状态的关键,是一个全局的 Safepoint Polling Page。 处于阻塞状态 在所有其他用户线程进入 SafePoint 之前,一直阻塞当前用户线程。 处于线程切换状态 一直轮询该用户线程状态,直到线程处于阻塞状态。 

参考:
JVM源码分析之安全点safepoint

3.5 SafePoint日志记录和分析

配置 -XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1 参数,

-XX:+PrintSafepointStatistics 打印安全点统计信息, -XX:PrintSafepointStatisticsCount=n 设置打印安全点统计信息的次数; 

3.6 日志分析:

1. vmop: 引发STW的原因,以及触发时间,本例中是GC。该项常见的输出有:RevokeBias、BulkRevokeBias、Deoptimize、G1IncCollectionPause。 数字.812是虚拟机启动后运行的秒数。GC log可以根据该项内容定位Total time for which application threads…引发的详细信息。 vmop 输出说明 RevokeBias、BulkRevokeBias、偏向锁取消情况。 Deoptimize、 G1IncCollectionPause GC GC 执行情况。 2. total : STW发生时,JVM存在的线程数目。 3. initially_running : STW发生时,仍在运行的线程数,这项是Spin阶段的 时间来源 4. wait_to_block : STW需要阻塞的线程数目,这项是block阶段的时间来源 5. sync = spin + block + 其他。 

3.7 由日志可以看出safepoint的执行分为四个阶段:

1. Spin阶段。因为jvm在决定进入全局safepoint的时候,有的线程在安全点上,而有的线程不在安全点上,这个阶段是等待未在安全点上的用户线程进入安全点。 2. Block阶段。即使进入safepoint,用户线程这时候仍然是running状态,保证用户不在继续执行,需要将用户线程阻塞。 3. Cleanup。这个阶段是JVM做的一些内部的清理工作。 4. VM Operation. JVM 执行的一些全局性工作,例如 GC, 代码反优化。 

3.8 优化说明

分析 -XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1 产生的日志信息基本上STW的原因都是RevokeBias或者BulkRevokeBias。 这个是撤销偏向锁操作,虽然每次暂停的 时间很短,但是特别频繁出现也会很耗时。 一些高并发的系统中,禁掉JVM偏向锁优化,可以提升系统的吞吐量。 禁用偏向锁的参数为: -XX:-UseBiasedLocking 

3.9 引起长时间STW原因

- GC - RevokeBias 撤销偏向锁操作也会消耗很长时间。在高并发系统中,建议禁用偏向锁。 - 撤销偏向锁,增加 -XX:-UseBiasedLocking 虚拟机参数 

4. 示例代码

  1. 被STW中断的应用程序线程会在完成GC之后恢复,频繁的中断会让用户感觉像是网速不快造成的电影卡顿一样,所以我们要减少STW的发生
  2. STW事件和采用哪款GC无关,所有的GC都有这个事件。
  3. 哪怕是G1也不能完全避免STW情况发生,只能说垃圾回收器越来越优秀,回收效率越来越高,尽可能地缩短了暂停时间。
  4. STW是JVM在后台自动发起和自动完成的。在用户不可见的情况下,把用户正常的工作线程全部停掉。
  5. 开发中采用System.gc();会导致STW的发生。
package com.zishi.jvm; import java.util.ArrayList; import java.util.List; public class StopTheWorldDemo { 
    public static class WorkThread extends Thread { 
    List<byte[]> list = new ArrayList<byte[]>(); public void run() { 
    try { 
    while (true) { 
    for(int i = 0;i < 1000;i++){ 
    byte[] buffer = new byte[1024]; list.add(buffer); } if(list.size() > 10000){ 
    list.clear(); System.gc();//会触发full gc,进而会出现STW事件 } } } catch (Exception ex) { 
    ex.printStackTrace(); } } } public static class PrintThread extends Thread { 
    public final long startTime = System.currentTimeMillis(); public void run() { 
    try { 
    while (true) { 
    // 每秒打印时间信息 long t = System.currentTimeMillis() - startTime; System.out.println(t / 1000 + "." + t % 1000); Thread.sleep(1000); } } catch (Exception ex) { 
    ex.printStackTrace(); } } } public static void main(String[] args) { 
    WorkThread w = new WorkThread(); PrintThread p = new PrintThread(); w.start(); p.start(); } } 
0.0 1.100 2.103 3.112 4.122 5.134 6.143 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/127357.html

(0)
上一篇 2025-09-08 12:33
下一篇 2025-09-08 12:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信