jvm-垃圾回收随时都可以STW吗?带你认识安全点和安全区域
目錄
安全點(diǎn)
如何在GC發(fā)生時(shí),檢查所有線程都跑到最近的安全點(diǎn)停頓下來呢?
安全區(qū)域(Safe?Region)
實(shí)際執(zhí)行時(shí)
安全點(diǎn)
1.程序執(zhí)行時(shí)并非在所有地方都能停頓下來開始GC,只有在特定的位置才能停頓下來開始GC,這些位置稱為“安全點(diǎn)(Safepoint)”。
2.Safe?Point的選擇很重要,如果太少可能導(dǎo)致GC等待的時(shí)間太長(zhǎng),如果太頻繁可能導(dǎo)致運(yùn)行時(shí)的性能問題。大部分指令的執(zhí)行時(shí)間都非常短暫,通常會(huì)根據(jù)“是否具有讓程序長(zhǎng)時(shí)間執(zhí)行的特征”為標(biāo)準(zhǔn)。比如:選擇一些執(zhí)行時(shí)間較長(zhǎng)的指令作為Safe?Point,如方法調(diào)用、循環(huán)跳轉(zhuǎn)和異常跳轉(zhuǎn)等。
如何在GC發(fā)生時(shí),檢查所有線程都跑到最近的安全點(diǎn)停頓下來呢?
1.搶先式中斷:(目前沒有虛擬機(jī)采用了)
? ? 首先中斷所有線程。如果還有線程不在安全點(diǎn),就恢復(fù)線程,讓線程跑到安全點(diǎn)。
2.主動(dòng)式中斷:
? ? 設(shè)置一個(gè)中斷標(biāo)志,各個(gè)線程運(yùn)行到Safe?Point的時(shí)候主動(dòng)輪訓(xùn)這個(gè)標(biāo)志,如果中斷標(biāo)志位真,則將自己進(jìn)行中斷掛起。
安全區(qū)域(Safe?Region)
1.SafePoint機(jī)制保證了程序執(zhí)行時(shí),在不太長(zhǎng)的時(shí)間內(nèi)就會(huì)遇到可進(jìn)入GC的SafePoint。但是,程序“不執(zhí)行”的時(shí)候呢?例如線程處于Sleep狀態(tài)或Blocked狀態(tài),這時(shí)候線程無法響應(yīng)JVM的中斷請(qǐng)求,“走”到安全點(diǎn)去中斷掛起,JVM也不太可能等待線程被喚醒。對(duì)于這種情況,就需要安全區(qū)域(Safe?Region)來解決。
2.安全區(qū)域是指在一段代碼片段中,對(duì)象的引用關(guān)系不會(huì)發(fā)生變化,在這個(gè)區(qū)域中的任何位置開始GC都是安全的。我們也可以把Safe?Region看作是被擴(kuò)展了的SafePoint。
實(shí)際執(zhí)行時(shí)
1.當(dāng)線程運(yùn)行到Safe?Region的代碼時(shí),首先標(biāo)識(shí)已經(jīng)進(jìn)入了Safe?Region,如果這段時(shí)間內(nèi)發(fā)生GC,JVM會(huì)忽略標(biāo)識(shí)為Safe?Region狀態(tài)的線程;
2.當(dāng)線程即將離開Safe?Region時(shí),會(huì)檢查JVM是否已經(jīng)完成GC,如果完成了,則繼續(xù)運(yùn)行,否則線程必須等待直到收到可以安全離開Safe?Region的信號(hào)為止。
總結(jié)
以上是生活随笔為你收集整理的jvm-垃圾回收随时都可以STW吗?带你认识安全点和安全区域的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 认识java-STW:Stop the
- 下一篇: java强引用、软引用、弱引用、虚引用-