溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

GC是怎么快速枚舉根節(jié)點(diǎn)的

發(fā)布時(shí)間:2021-12-21 10:25:42 來源:億速云 閱讀:137 作者:柒染 欄目:大數(shù)據(jù)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)GC是怎么快速枚舉根節(jié)點(diǎn)的,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

Java一個(gè)優(yōu)點(diǎn)就是GC(Garbage Collection),雖然它能幫我們管理內(nèi)存,但是它工作的時(shí)候會(huì)STW(Stop the World)。也就是停止所有的工作線程,"你們先別干活,我先來清理清理垃圾!"。

那就出問題了啊,你想想比如你在玩游戲的時(shí)候,電腦來個(gè)STW停個(gè)幾秒鐘時(shí)間,清理下垃圾。你可能就會(huì)"****",你隊(duì)友可能也會(huì)"***"。

但是現(xiàn)在常用的一些垃圾收集器都得STW,雖然各種垃圾收集器已經(jīng)各種絞盡腦汁減少STW的時(shí)間,但是做不到避免STW。具體的各種垃圾收集器的對(duì)比下次單獨(dú)寫一篇文章。

今天先來講述一下GC是如何快速枚舉根節(jié)點(diǎn)。在HotSpot虛擬機(jī)中,是通過可達(dá)性分析來判斷此對(duì)象是否需要回收的。那可達(dá)性分析就需要找到“源頭”,也就是根節(jié)點(diǎn)。

通過枚舉一個(gè)一個(gè)根節(jié)點(diǎn)(GC Roots),然后順藤摸瓜一路摸下來,然后沒摸到的那些對(duì)象就把它咔嚓回收了。那這個(gè)順藤摸瓜的過程就必須讓世界停止,也就是那些工作線程都得停了。

你想想如果不STW那對(duì)象引用關(guān)系變來變?nèi)サ模占鞯迷趺催青陮?duì)象啊,容易咔嚓錯(cuò)了,那咱們使用者不就急眼了啊。所以枚舉根節(jié)點(diǎn)時(shí)STW不可避免,所以只能讓STW盡量的短。

根節(jié)點(diǎn)主要在全局性的引用(常量、類靜態(tài)屬性)和執(zhí)行上下文(棧幀中的本地變量表)中。那我們?nèi)绻粋€(gè)一個(gè)的找過去就很慢。

并且我們的HotSpot又是準(zhǔn)確性GC,也就是它需要知道某個(gè)位置上的某個(gè)數(shù)據(jù)的類型,類型是準(zhǔn)確的。這樣它就能準(zhǔn)確的知道這塊數(shù)據(jù)類型是不是它關(guān)心的指針也就是引用啦!

在HotSpot中是用了一種叫OopMap的結(jié)構(gòu)來存放一個(gè)對(duì)象內(nèi)什么偏移量上是什么類型的數(shù)據(jù)。在類加載過程中就會(huì)進(jìn)行記錄。

可以把OopMap理解為一個(gè)附加信息,或者說一件衣服的吊牌,咱們看吊牌就知道這衣服啥做的。所以GC在掃描的時(shí)候就可以直接看這些“吊牌”來知道信息了。

在JIT編譯的時(shí)候也會(huì)在一些特定的位置記錄下OopMap,記錄了執(zhí)行到該方法的某條指令的時(shí)候,棧上和寄存器里哪些位置是引用,每個(gè)方法可能會(huì)有好多個(gè)OopMap,這是根據(jù)特定位置來決定的,這個(gè)特定位置會(huì)把這個(gè)方法分會(huì)好幾塊,每一塊都有一個(gè)OopMap。

這些特定的位置主要在:

1、方法臨返回前/調(diào)用方法的call指令后

2、循環(huán)的末尾

3、可能拋出異常的地方

這些特定的位置也叫安全點(diǎn)(Safepoint)。

之所以要在特定的位置才記錄OopMap,是因?yàn)槿绻麑?duì)每條指令都記錄一下的話,那就會(huì)需要大量的空間,提高了GC的空間成本,所以用一些比較關(guān)鍵的點(diǎn)來記錄就能有效的縮小記錄所需的空間。

因此GC不是隨時(shí)隨地來的,得到達(dá)安全點(diǎn)時(shí)才可以開始GC。

平時(shí)OopMap是壓縮在內(nèi)存中,只要當(dāng)要GC的時(shí)候才會(huì)解壓出來,然后開始遍歷來掃描對(duì)應(yīng)的偏移量。

對(duì)于JNI(Java Native Interface)方法,因?yàn)楸镜胤椒ê徒忉屍鳌IT編譯器沒啥關(guān)系,所以就沒有OopMap。

它的引用是加了個(gè)中間層一樣的,就是句柄,也就是引用不是直接指向堆中的對(duì)象,而是引用指向句柄,句柄指向堆中對(duì)象。所以GC直接掃描句柄就行了,不需要掃描棧幀。

上述就是小編為大家分享的GC是怎么快速枚舉根節(jié)點(diǎn)的了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

gc
AI