中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

為何跨代引用是GC root

發布時間:2022-01-05 19:32:11 來源:億速云 閱讀:177 作者:柒染 欄目:大數據

為何跨代引用是GC root,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

有人在一個JVM群里問了一個問題,為什么跨代引用是gc root。這雖然是一個很簡單的問題,但是其實涉及到了分代垃圾回收算法的核心理念。
 

gc root的基本解釋

首先我們要理解一下GC root究竟是什么東西。

為何跨代引用是GC root圖:gc root

堆是被我們垃圾回收所管理的內存空間。如圖,存在兩種引用,一種是堆外對象對堆內對象的引用,被標注為紅色;另外一種是堆內對象之間的引用,被標注為灰色。通常我們說的gc root就可以被認為是紅色的那種引用,比如說棧引用堆中對象。為什么我們不認為堆內對象之間的引用是gc root呢?因為我們的對象,最終是要被外部使用的,比如說被棧引用所訪問。因此,如果一大堆的堆內對象之間互相引用,但是沒有任何堆外部引用,那么這部分對象實際上也是不可達的。HotSpot就是如此的,所有的堆中的對象,最終都是被棧所使用的。因而,U和V就可以看做是不可達的對象了。

 

分代和跨代引用

解釋了gc root的基本概念后,我們要來看看分代理論了。基本上,現代垃圾回收器都是分代垃圾回收器,它建立在兩個分代理論之上:

  • 弱分代假說(weak generational hypothesis):大多數對象在年輕的時候死亡;

  • 強分代假說(strong generational hypothesis):越老的對象越難死亡;

這個分代假說引申出一種垃圾回收理念:將對象依據“年齡”分配到不同的區域,每次回收只回收其中的一個區域。這也就是分代回收的基礎理念。因為很顯然的,如果大部分對象都是朝生夕死的,那么將它們放在一起,每次回收都能夠回收到很多的空間;剩下的不容易死亡的對象,放在一起,那么可以以一種極為低的頻率來回收它們。這就兼顧了垃圾回收的時間開銷和內存的空間利用率。

一般的垃圾回收算法至少會劃分出兩個年代,年輕代和老年代。但是單純的分代理論在垃圾回收的時候存在一個巨大的缺陷:為了找到年輕代中的存活對象,卻不得不遍歷整個老年代,反過來也是一樣的。

為何跨代引用是GC root

圖:跨代引用引起老年代的遍歷

如果我們從年輕代開始遍歷,那么可以斷定N, S, P, Q都是存活對象。但是,V卻不會被認為是存活對象,其占據的內存會被回收了。這就是一個驚天的大漏洞!因為U本身是老年代對象,而且有外部引用指向它,也就是說U是存活對象,而U指向了V,也就是說V也應該是存活對象才是!而這都是因為我們只遍歷年輕代對象!

所以,為了解決這種跨代引用的問題,最笨的辦法就是遍歷老年代的對象,找出這些跨代引用來。這種方案存在極大的性能浪費。因為從兩個分代假說里面,其實隱含了一個推論:跨代引用是極少的。也就是為了找出那么一點點跨代引用,我們卻得遍歷整個老年代!從上圖來說,很顯然的是,我們根本不必遍歷R。

因此,為了避免這種遍歷老年代的性能開銷,通常的分代垃圾回收器會引入一種稱為記憶集的技術。簡單來說,記憶集就是用來記錄跨代引用的表。

為何跨代引用是GC root

圖:記憶集記錄跨代引用

如圖,在擁有記憶集的情況下,我們就可以不用遍歷老年代了,這是一個巨大的性能提升!

 

最終解釋

現在,我們設想一下,要回收年輕代,首先我們要從引用年輕代對象的外部引用開始;其次,我們要從跨代引用開始。于是我們可以很自然的得出結果:跨代引用也是gc root。

整個模型可以抽象成:

為何跨代引用是GC root

圖:gc root的最終解釋


 

附錄

在引入記憶集之后,其實會有一個很有意思的問題:即老年代對象即便已經事實上不可達了,但是因為記憶集的存在,會導致從該對象出發的跨代引用依舊會被當成gc root,直至該對象被回收引起記憶集中相關條目的擦除。

為何跨代引用是GC root

圖:記憶集引出的問題

如圖,U已經不存在外部引用了,所以它事實上已經不可達了。但是在這個時刻,因為老年代沒有發生GC,所以它依舊存活著。

  • 如果我們采用遍歷老年代的方法找出跨代引用,那么我們只能找到S->P這一條。于是U和V都會被當成是不可達對象,其內存空間就可以被回收掉了。

  • 如果我們使用記憶集,那么因為U沒有被GC掉,所以記憶集里面的條目U->V依舊存在,所以在年輕代回收的時候,V會被當成存活對象。

這個問題就是因為使用記憶集帶來的“滯后性”,它提高了時間效率,但是卻降低了空間利用率。不過無論如何,它依然確保了垃圾回收所遵循的原則:垃圾回收確保回收的對象必然是不可達對象,但是不確保所有的不可達對象都會被回收

看完上述內容,你們掌握為何跨代引用是GC root的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

临江市| 佳木斯市| 正定县| 新乡市| 闸北区| 迁安市| 黔南| 渝北区| 获嘉县| 墨玉县| 远安县| 三原县| 克山县| 全南县| 乐昌市| 湘潭县| 班戈县| 澄江县| 子洲县| 平塘县| 凯里市| 富顺县| 璧山县| 武穴市| 宿州市| 廊坊市| 安塞县| 眉山市| 霍山县| 定结县| 恩施市| 徐水县| 绿春县| 射阳县| 禄丰县| 通榆县| 霞浦县| 年辖:市辖区| 林口县| 甘洛县| 辽阳县|