一 点睛
stop-the-world,简称 STW,指的是 GC 事件发生过程中,会产生应用程序的停顿。停顿产生时整个应用程序线程都会被暂停,没有任何响应,有点像卡死的感觉,这个停顿称为 STW。
可达性分析算法中枚举根节点(GC Roots)会导致所有 Java 执行线程停顿。
-
分析工作必须在一个能确保一致性的快照中进行
-
一致性指整个分析期间整个执行系统看起来像被冻结在某个时间点上
-
如果出现分析过程中对象引用关系还在不断变化,则分析结果的准确性无法保证
被 STW 中断的应用程序线程会在完成 GC 之后恢复,频繁中断会让用户感觉像是网速不快造成电影卡顿一样,所以我们需要减少 STW 的发生。
STW 事件和采用哪款 GC 无关,所有的 GC 都有这个事件。
哪怕是 G1 也不能完全避免 Stop-the-world 情况发生,只能说垃圾回收器越来越优秀,回收效率越来越高,尽可能地缩短了暂停时间。
STW 是 JVM 在后台自动发起和自动完成的。在用户不可见的情况下,把用户正常的工作线程全部停掉。
开发中不要用 system.gc(),会导致 stop-the-world 的发生。
二 实战
1 代码
/**
* 测试 Stop The World
*/
public class StopTheWorldDemo {
public static class WorkThread extends Thread {
List<byte[]> list = new ArrayList<byte[]>();
// 主要任务是制造垃圾,进而触发 full gc
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();
}
}
}
// 1秒大于1次
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();
}
}
2 测试
0.0
1.1
2.7
3.22
4.32
5.39
6.40
7.48
8.55
9.56
10.67
11.68
3 说明
不是每隔1秒大于一次,是因为发生了 Stop The World。