JVM基础:什么是STW?

今天笔试题,出了个STW,咱是见也没见过,漏了怯了

无语,仔细回忆了下,知道Stop-The-World这个词,不知道SWT,无语

STW:Stop-The-World

STW概念

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

一旦Stop-the-world发生,除了GC所需的线程外,其他线程都将停止工作,中断了的线程直到GC任务结束才继续它们的任务。

STW是不可避免的,垃圾回收算法执行一定会出现STW,我们要做的只是减少停顿的时间,所以 GC各种算法优化的重点,就是减少STW(暂停),同时这也是JVM调优的重点。

进入SWT时机

当可达性分析算法中枚举根节点(GC Roots)会导致所有Java执行线程停顿,进入STW状态

STW停顿的原因

首先,分析工作必须在一个能确保一致性的快照中进行,如果出现分析过程中对象引用关系还在不断变化,则分析结果的准确性无法保证,被STW中断的应用程序线程会在完成GC之后恢复,频繁的中断会让用户感觉卡顿

一致性指整个分析期间整个执行系统看起来像被冻结在某个时间点上

所以我们要减少STW的发生,也就相当于要想办法降低GC垃圾回收的频率,STW状态和采用哪款GC收集器无关,所有的GC收集器都有这个状态,因为要保证一致性。

但是好的GC收集器可以减少停顿的时间,减少STW(暂停)和降低GC垃圾回收的频率是调优的重点,如果系统卡顿很明显,大概率就是频繁执行GC垃圾回收,频繁进入STW状态产生停顿的缘故

STW示例代码

代码如下:

package com.yyl.threadTest;

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();
    }
}

P线程执行每隔一秒打印一次,当没有w线程时的输出秒数间隔规律为1秒。

但当同时运行w线程时,W线程当中的GC触发了STW,进而干扰了P线程有规律性打印。打印变得杂乱无章

image-20220924231804706

猜你喜欢

转载自blog.csdn.net/weixin_45525272/article/details/127032638