為何跨代引用是GC root,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
創(chuàng)新互聯(lián)主打移動(dòng)網(wǎng)站、成都做網(wǎng)站、網(wǎng)站建設(shè)、網(wǎng)站改版、網(wǎng)絡(luò)推廣、網(wǎng)站維護(hù)、域名注冊(cè)、等互聯(lián)網(wǎng)信息服務(wù),為各行業(yè)提供服務(wù)。在技術(shù)實(shí)力的保障下,我們?yōu)榭蛻舫兄Z穩(wěn)定,放心的服務(wù),根據(jù)網(wǎng)站的內(nèi)容與功能再?zèng)Q定采用什么樣的設(shè)計(jì)。最后,要實(shí)現(xiàn)符合網(wǎng)站需求的內(nèi)容、功能與設(shè)計(jì),我們還會(huì)規(guī)劃穩(wěn)定安全的技術(shù)方案做保障。
首先我們要理解一下GC root究竟是什么東西。
圖:gc root
堆是被我們垃圾回收所管理的內(nèi)存空間。如圖,存在兩種引用,一種是堆外對(duì)象對(duì)堆內(nèi)對(duì)象的引用,被標(biāo)注為紅色;另外一種是堆內(nèi)對(duì)象之間的引用,被標(biāo)注為灰色。通常我們說的gc root就可以被認(rèn)為是紅色的那種引用,比如說棧引用堆中對(duì)象。為什么我們不認(rèn)為堆內(nèi)對(duì)象之間的引用是gc root呢?因?yàn)槲覀兊膶?duì)象,最終是要被外部使用的,比如說被棧引用所訪問。因此,如果一大堆的堆內(nèi)對(duì)象之間互相引用,但是沒有任何堆外部引用,那么這部分對(duì)象實(shí)際上也是不可達(dá)的。HotSpot就是如此的,所有的堆中的對(duì)象,最終都是被棧所使用的。因而,U和V就可以看做是不可達(dá)的對(duì)象了。
解釋了gc root的基本概念后,我們要來看看分代理論了。基本上,現(xiàn)代垃圾回收器都是分代垃圾回收器,它建立在兩個(gè)分代理論之上:
弱分代假說(weak generational hypothesis):大多數(shù)對(duì)象在年輕的時(shí)候死亡;
強(qiáng)分代假說(strong generational hypothesis):越老的對(duì)象越難死亡;
這個(gè)分代假說引申出一種垃圾回收理念:將對(duì)象依據(jù)“年齡”分配到不同的區(qū)域,每次回收只回收其中的一個(gè)區(qū)域。這也就是分代回收的基礎(chǔ)理念。因?yàn)楹茱@然的,如果大部分對(duì)象都是朝生夕死的,那么將它們放在一起,每次回收都能夠回收到很多的空間;剩下的不容易死亡的對(duì)象,放在一起,那么可以以一種極為低的頻率來回收它們。這就兼顧了垃圾回收的時(shí)間開銷和內(nèi)存的空間利用率。
一般的垃圾回收算法至少會(huì)劃分出兩個(gè)年代,年輕代和老年代。但是單純的分代理論在垃圾回收的時(shí)候存在一個(gè)巨大的缺陷:為了找到年輕代中的存活對(duì)象,卻不得不遍歷整個(gè)老年代,反過來也是一樣的。

圖:跨代引用引起老年代的遍歷
如果我們從年輕代開始遍歷,那么可以斷定N, S, P, Q都是存活對(duì)象。但是,V卻不會(huì)被認(rèn)為是存活對(duì)象,其占據(jù)的內(nèi)存會(huì)被回收了。這就是一個(gè)驚天的大漏洞!因?yàn)閁本身是老年代對(duì)象,而且有外部引用指向它,也就是說U是存活對(duì)象,而U指向了V,也就是說V也應(yīng)該是存活對(duì)象才是!而這都是因?yàn)槲覀冎槐闅v年輕代對(duì)象!
所以,為了解決這種跨代引用的問題,最笨的辦法就是遍歷老年代的對(duì)象,找出這些跨代引用來。這種方案存在極大的性能浪費(fèi)。因?yàn)閺膬蓚€(gè)分代假說里面,其實(shí)隱含了一個(gè)推論:跨代引用是極少的。也就是為了找出那么一點(diǎn)點(diǎn)跨代引用,我們卻得遍歷整個(gè)老年代!從上圖來說,很顯然的是,我們根本不必遍歷R。
因此,為了避免這種遍歷老年代的性能開銷,通常的分代垃圾回收器會(huì)引入一種稱為記憶集的技術(shù)。簡(jiǎn)單來說,記憶集就是用來記錄跨代引用的表。

圖:記憶集記錄跨代引用
如圖,在擁有記憶集的情況下,我們就可以不用遍歷老年代了,這是一個(gè)巨大的性能提升!
現(xiàn)在,我們?cè)O(shè)想一下,要回收年輕代,首先我們要從引用年輕代對(duì)象的外部引用開始;其次,我們要從跨代引用開始。于是我們可以很自然的得出結(jié)果:跨代引用也是gc root。
整個(gè)模型可以抽象成:

圖:gc root的最終解釋
在引入記憶集之后,其實(shí)會(huì)有一個(gè)很有意思的問題:即老年代對(duì)象即便已經(jīng)事實(shí)上不可達(dá)了,但是因?yàn)橛洃浖拇嬖冢瑫?huì)導(dǎo)致從該對(duì)象出發(fā)的跨代引用依舊會(huì)被當(dāng)成gc root,直至該對(duì)象被回收引起記憶集中相關(guān)條目的擦除。

圖:記憶集引出的問題
如圖,U已經(jīng)不存在外部引用了,所以它事實(shí)上已經(jīng)不可達(dá)了。但是在這個(gè)時(shí)刻,因?yàn)槔夏甏鷽]有發(fā)生GC,所以它依舊存活著。
如果我們采用遍歷老年代的方法找出跨代引用,那么我們只能找到S->P這一條。于是U和V都會(huì)被當(dāng)成是不可達(dá)對(duì)象,其內(nèi)存空間就可以被回收掉了。
如果我們使用記憶集,那么因?yàn)閁沒有被GC掉,所以記憶集里面的條目U->V依舊存在,所以在年輕代回收的時(shí)候,V會(huì)被當(dāng)成存活對(duì)象。
這個(gè)問題就是因?yàn)槭褂糜洃浖瘞淼摹皽笮浴保岣吡藭r(shí)間效率,但是卻降低了空間利用率。不過無論如何,它依然確保了垃圾回收所遵循的原則:垃圾回收確保回收的對(duì)象必然是不可達(dá)對(duì)象,但是不確保所有的不可達(dá)對(duì)象都會(huì)被回收。
看完上述內(nèi)容,你們掌握為何跨代引用是GC root的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!
網(wǎng)頁(yè)標(biāo)題:為何跨代引用是GCroot
本文鏈接:http://chinadenli.net/article36/jpspsg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、域名注冊(cè)、網(wǎng)站策劃、微信公眾號(hào)、網(wǎng)站制作、品牌網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)