0
点赞
收藏
分享

微信扫一扫

Stop-the-World(STW)


Stop-the-World,简称 STW,指的是 GC 事件/过程4发生过程当中停止所有的应用程序线程的执行。 这让我想起了我丈母娘对我喊 着: “我扫垃圾的时候你站在原地不要动”。

垃圾回收器的任务是识别和回收垃圾对象进行内存清理。为了让垃圾回收器可以正常且高 效地执行,大部分情况下会要求系统进入一个停顿的状态。停顿的目的是终止所有应用程序的 执行,只有这样,系统中才不会有新的垃圾产生,同时停顿保证了系统状态在某一个瞬间的一 致性,也有益于垃圾回收器更好地标记垃圾对象。因此,在垃圾回收时,都会产生应用程序的 停顿。停顿产生时整个应用程序会被暂停,没有任何响应,有点像卡死的感觉,这个停顿称为
STW。

代码清单 例子说明垃圾回收对应用程序产生的影响。模拟当生产环境系统出现严重性 能问题,即尝试重现了 Stop-the-World 现象。

public class StopWorldDemo {
public static class MyThread extends Thread {
HashMap map = new HashMap();

public void run() {
try {
while (true) {
if (map.size() * 512 / 1024 / 1024 >= 400) {
map.clear();//防止内存溢出
System.out.println("clean map");
}
byte[] bl;
for (int i = 0; i < 100; i++) {
bl = new byte[512];//模拟内存占用
map.put(System.nanoTime(), bl);
}
}
} 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) {
MyThread t = new MyThread();
PrintThread p = new PrintThread();
t.start();
p.start();
}
}

上述代码中定义了两个线程,分别是 MyTbread 和 PrintThread。 MyTbread 不停地申请系统 内存,这会迫使进行垃圾回收, PrintTbread 则每隔 O.ls 打印出系统启动时间。正常情况下应该 ls 有 10 个输出.

实际运行时些 GC 严重干扰了 PrintThread 的正常工作。

当通过 Stop-the-World 机制的方式来运行垃圾收集器时, 垃圾收集器会在内存回收的过程 中暂停程序中所有的工作线程,直至完成内存回收才会恢复之前被暂停的工作线程。 如果 Stop-the-World 出现在新生代的 MinorGC 中时, 由于新生代的内存空间通常都比较小, 所以暂 停时间也在可接受的合理范围之内,不过一旦出现在老年代的 Full GC 中时,程序的工作线程 被暂停的时间将会更久, 这往往直接跟 Java 堆空间所管理的内存大小有关。 简单来说,内存空 间越大,执行 Full GC 的时间就会越久, 相对的工作线程被暂停的时间也就会更长。 以互联网 项目为例,由于项目的特殊性,因此经常需要用到多达几十乃至上百 GB 的内存, 如果用户的 登录操作恰巧碰见垃圾收集器在执行 Full GC 时, 这将会是一场灾难。 如果用户等待的时间过 长, 这就不是用户体验下降这么简单的事情了 , 甚至有可能会流失用户 , 所以 JVM 的设计者们 提供了并发回收希望以此缩短 Stop-the-world 机制的暂停时间。 直到目前为止,哪怕是 Gl 也不 能完全避免 Stop-the-world 情况发生,只能说垃圾回收器越来越优秀,回收效率越来越高, 尽可 能地缩短了暂停时间。

STW 事件和采用哪款 GC 无关, 所有的 GC 都有这个事件。 被 STW 中断的应用程序线程 会在完成 GC 之后恢复, 频繁中断会让用户感觉像是网速不快造成电影卡带一样,所以我们需 要减少 STW 的发生。 另外, 既然有 “Stop-the-World”,那一定有能和 GC 事件/过程同时执行 的 Java 应用线程。


举报

相关推荐

0 条评论