Java中的?stop?the?world是什么呢
一、概述;
從字面上講,就是停止這個世界,看到這個字眼,就覺得這是可怕的事情,那到底什么是stop-the-world?
stop-the-world,簡稱 STW,指的是 GC 事件發(fā)生過程中,會產(chǎn)生應(yīng)用程序的停頓。停頓產(chǎn)生時整個應(yīng)用程序線程都會被暫停,沒有任何響應(yīng),有點像卡死的感覺,這個停頓稱為 STW。
舉例:
可達(dá)性分析算法中枚舉根節(jié)點(GC Roots)會導(dǎo)致所有Java執(zhí)行線程停頓。
停頓的原因:
- 分析工作必須在一個能確保一致性的快照中進(jìn)行
- 一致性指整個分析期間整個執(zhí)行系統(tǒng)看起來像被凍結(jié)在某個時間點上
- 如果出現(xiàn)分析過程中對象引用關(guān)系還在不斷變化,則分析結(jié)果的準(zhǔn)確性無法保證
二、為什么需要STW(stop the world)
垃圾回收是根據(jù)可達(dá)性分析算法,搜索GC Root根的引用鏈,將不在引用鏈上的對象當(dāng)做垃圾回收,設(shè)想我們執(zhí)行某個方法的時候,此時產(chǎn)生了很多局部變量,剛好老年代滿了需要進(jìn)行Full gc,如果不停止線程,垃圾回收正在根據(jù)這些局部變量也就是GC Root根搜索引用鏈,此時這個方法結(jié)束了,那么這些局部變量就都會被銷毀,這些引用鏈的GC Root根都銷毀了,這些引用當(dāng)然也成了垃圾對象,這樣就會導(dǎo)致在垃圾回收的過程中還會不斷的產(chǎn)生新的垃圾。
但是Stop-The-World的結(jié)果是比較嚴(yán)重的,如果用戶正在瀏覽你的網(wǎng)站,應(yīng)用程序突然Stop-The-World,所有線程被掛起,那么用戶就會感覺你的網(wǎng)站卡住了,盡管gc時間是比較快的,但是如果并發(fā)量比較大,用戶感知是比較明顯的,會影響用戶體驗。
簡明地說:
java進(jìn)行垃圾回收時使用可達(dá)性分析,從GC Root向下判斷對象是否有引用,如果不把所有線程進(jìn)入safe points并阻塞起來就會出現(xiàn)對象上一秒沒有引用被刪除,后一秒又出現(xiàn)引用,導(dǎo)致錯誤的產(chǎn)生
三、stop-the-world示例:
被 STW 中斷的應(yīng)用程序線程會在完成 GC 之后恢復(fù),頻繁中斷會讓用戶感覺像是網(wǎng)速不快造成電影卡頓一樣,所以我們需要減少 STW 的發(fā)生。
STW 事件和采用哪款 GC 無關(guān),所有的 GC 都有這個事件。
哪怕是G1也不能完全避免Stop一the一world情況發(fā)生,只能說垃圾回收器越來越優(yōu)秀,回收效率越來越高,盡可能地縮短了暫停時間。
STW是JVM在后臺自動發(fā)起和自動完成的。在用戶不可見的情況下,把用戶正常的工作線程全部停掉。
開發(fā)中采用System.gc();會導(dǎo)致Stop一the一world的發(fā)生。
源碼:
import java.util.ArrayList;
import java.util.List;
public class StopTheWorldDemo {
public static void main(String[] args) {
WorkThread w = new WorkThread();
PrintThread p = new PrintThread();
w.start();
p.start();
}
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();//會觸發(fā)full gc,進(jìn)而會出現(xiàn)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();
}
}
}
}運(yùn)行結(jié)果:

從結(jié)果可以看出:
W線程當(dāng)中的GC觸發(fā)了STW,進(jìn)而干擾了P線程有規(guī)律性打印。打印變得雜亂無章
源碼下載:
gitee.com/charlinchenlin/koo-erp
到此這篇關(guān)于Java中的 stop the world是什么呢的文章就介紹到這了,更多相關(guān)java stop the world內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中OutOfMemoryError錯誤的原因分析及解決指南
你是否遇到過程序突然崩潰并顯示"OutOfMemoryError"的錯誤?別擔(dān)心!這是每個Java開發(fā)者成長的必經(jīng)之路,本文將用簡單易懂的方式帶你理解這個常見問題,并提供實用的解決方案,需要的朋友可以參考下2025-06-06
IDEA?Error:java:無效的源發(fā)行版:13的解決過程
之前用idea運(yùn)行時,也會出現(xiàn)這種情況,后面通過網(wǎng)上的資料解決了這個問題,下面這篇文章主要給大家介紹了關(guān)于IDEA?Error:java:無效的源發(fā)行版:13的解決過程,需要的朋友可以參考下2023-01-01
SharedWorkerGlobalScope屬性數(shù)據(jù)共享示例解析
這篇文章主要為大家介紹了SharedWorkerGlobalScope屬性數(shù)據(jù)共享示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
IDEA生成項目maven-tree依賴目錄樹結(jié)構(gòu)方式
這篇文章主要介紹了IDEA生成項目maven-tree依賴目錄樹結(jié)構(gòu)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
Java 遞歸遍歷實現(xiàn)linux tree命令方式
這篇文章主要介紹了Java 遞歸遍歷實現(xiàn)linux tree命令方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
詳解Java弱引用(WeakReference)的理解與使用
這篇文章主要介紹了Java弱引用(WeakReference)的理解與使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04

