欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JVM回收跨代垃圾的方式詳解

 更新時(shí)間:2024年02月27日 08:26:02   作者:半畝方塘立身  
在Java堆內(nèi)存中,年輕代和老年代之間存在的對(duì)象相互引用,假設(shè)現(xiàn)在要進(jìn)行一次新生代的YGC,但新生代中的對(duì)象可能被老年代所引用的,為了找到新生代中的存活對(duì)象,不得不遍歷整個(gè)老年代,這樣明顯效率很低下,那么如何快速識(shí)別并回收這種引用對(duì)象呢

1. 跨代引用概述

在Java堆內(nèi)存中,年輕代和老年代之間存在的對(duì)象相互引用,假設(shè)現(xiàn)在要進(jìn)行一次新生代的YGC,但新生代中的對(duì)象可能被老年代所引用的,為了找到新生代中的存活對(duì)象,不得不遍歷整個(gè)老年代。這樣明顯效率很低下,那么如何快速識(shí)別并回收這種引用對(duì)象呢?

這就不得不提到Card Table(卡表)和 Remember Set(記憶集,簡稱RSet)了。

2. 跨代引用的處理方式

2.1 卡表(Card Table)

卡表是一種用于跟蹤年輕代對(duì)象被老年代對(duì)象引用的數(shù)據(jù)結(jié)構(gòu)。它將堆內(nèi)存劃分為一系列固定大小的區(qū)域(卡片),每個(gè)卡片記錄了年輕代對(duì)象被老年代對(duì)象引用的情況。在老年代垃圾回收時(shí),垃圾收集器會(huì)掃描卡表,以確定哪些年輕代對(duì)象是存活的,即被老年代對(duì)象引用。

在 JVM 中,一個(gè) card 的大?。ㄍǔJ牵?12字節(jié)。在多線程并行收集時(shí),每個(gè)線程可以批量掃描多個(gè) card,一批 card 被稱為一個(gè) stride。默認(rèn)一個(gè) stride 含有 256個(gè) card,即每個(gè)線程要每次掃描 512 * 256 = 128 K 的內(nèi)存區(qū)域。stride數(shù)量太多就會(huì)導(dǎo)致線程在stride之間切換的開銷增加,進(jìn)而導(dǎo)致 GC Pause 增長, strides 太少恐怕也會(huì)導(dǎo)致單次掃描的時(shí)間增長,進(jìn)而影響整個(gè) GC Pause 。

2.2 記憶集(Remembered Sets)

伴隨 G1 垃圾收集器的誕生,傳統(tǒng)的老年代和新生代都從物理上的連續(xù)空間,變成了一個(gè)個(gè)物理上不連續(xù)的空間 region。

JVM 針對(duì)這些Region 提供了一個(gè)數(shù)據(jù)結(jié)構(gòu),也就是 CSet(Collection Set),存儲(chǔ)任意年代的region。

物理上不連續(xù)的 region 造成了新生代和老年的引用破碎化,新生代引用老年代,所以產(chǎn)生了 old->youngyoung->old的跨代對(duì)象引用,這時(shí)候 JVM 只要掃描 CSet 中的 R Set 即可。

邏輯上說每個(gè)Region都有一個(gè)RSet,RSet記錄了其他Region中的對(duì)象引用本Region中對(duì)象的關(guān)系。

每個(gè)Region會(huì)在自身的Remembered Set中紀(jì)錄下來自其他Region的指向自身的Card位置。這個(gè)Remembered Set是一個(gè)Hash Table,Key是別的Region的起始地址,Value是一個(gè)集合,里面的元素是Card Table的Index。

RSet、Card和Region的關(guān)系

下圖表示了RSet、Card和Region的關(guān)系: 

圖中是相互引用的三個(gè)region。R1 和 R3 的被細(xì)分到了card table 級(jí)別。R2 被 R1 和 R3的某些區(qū)域引用,所以 R2 的 RSet 會(huì)記錄到 R1 和 R2 的區(qū)域索引,即產(chǎn)生某些循環(huán)引用的作用。

一個(gè) Region 的 RSet 如果有值,至少可以證明這個(gè)區(qū)域是有引用的;一個(gè)區(qū)域如果無值,則可以認(rèn)為這個(gè)區(qū)域不可達(dá),可以不掃描這個(gè)區(qū)域(Card Table 可以減少 Minor GC 掃描 old 區(qū)來理解 young 區(qū)的時(shí)間,RSet 則可以減少掃描生成 CSet 選取候選 region 的時(shí)間)。

在做YGC的時(shí)候,只需要選定young generation region的RSet作為根集,這些RSet記錄了old->young的跨代引用,避免了掃描整個(gè)old generation。而mixed gc的時(shí)候,old generation中記錄了old->old的 RSet,young->old的引用由掃描全部young generation region(的 card table)得到,這樣也不用掃描全部old generation region。所以RSet的引入大大減少了GC的工作量。

2.3 處理器屏障(Processor Barriers)

處理器屏障是一種硬件支持的機(jī)制,用于跟蹤對(duì)象之間的引用關(guān)系。當(dāng)發(fā)生引用修改時(shí),處理器屏障可以監(jiān)測(cè)到對(duì)內(nèi)存的訪問,并通知垃圾收集器。垃圾收集器可以根據(jù)這些信息來更新引用關(guān)系,確??绱帽徽_處理。

3. 總結(jié)

卡表只解決 youngGC 掃老年代的問題,而 RSet 則解決了(G1 對(duì))所有 Region 的掃描問題。卡表通過對(duì)外引用提示我們應(yīng)該掃描什么區(qū)域,這樣我們可以避開不用掃描的區(qū)域;RSet通過對(duì)內(nèi)引用提示我們應(yīng)該掃描什么區(qū)域,這樣我們可以避開不用掃描的區(qū)域。

跨代引用的垃圾回收是Java虛擬機(jī)中一個(gè)復(fù)雜而重要的問題。通過合理設(shè)計(jì)和優(yōu)化記憶集、卡表等數(shù)據(jù)結(jié)構(gòu),并結(jié)合并發(fā)標(biāo)記-清除算法、處理器屏障等技術(shù),可以有效地處理跨代引用,保證垃圾回收的效率和穩(wěn)定性,從而提高Java應(yīng)用程序的性能和可靠性。

以上就是JVM回收跨代垃圾的方式詳解的詳細(xì)內(nèi)容,更多關(guān)于JVM回收跨代垃圾的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論