最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?垃圾回收超詳細(xì)講解記憶集和卡表

 更新時(shí)間:2022年04月07日 18:47:11   作者:田埂、  
卡表就是記憶集的一種具體實(shí)現(xiàn),它定義了記憶集的記錄精度、與堆內(nèi)存的映射關(guān)系等。?關(guān)于卡表與記憶集的關(guān)系,不妨按照J(rèn)ava語言中HashMap與Map的關(guān)系來類比理解。記憶集是一種用于記錄從非收集區(qū)域指向收集區(qū)域的指針集合的抽象數(shù)據(jù)結(jié)構(gòu)

跨代引用

在說記憶集和卡表之前,先給大家介紹一下跨代引用的問題。

假如要現(xiàn)在進(jìn)行一次只局限于新生代區(qū)域內(nèi)的收集(Minor GC),但新生代的實(shí)例對(duì)象1在老年代中被引用,為了找出該區(qū)域(新生代)中所有的存活對(duì)象,不得不在固定的GC Roots之外,再額外遍歷整個(gè)老年代中所有對(duì)象來確??蛇_(dá)性分析結(jié)果的正確性,反過來也是一樣。遍歷整個(gè)老年代所有對(duì)象的方案雖然理論上可行,但無疑會(huì)為內(nèi)存回收帶來很大的性能負(fù)擔(dān)。

事實(shí)上并不只是新生代、老年代之間才有跨代引用的問題,所有涉及部分區(qū)域收集(Partial GC)行為的垃圾收集器,典型的如G1、ZGC和Shenandoah收集器,都會(huì)面臨相同的問題。

解決跨代引用

首先,跨代引用相對(duì)于同代引用來說僅占極少數(shù)。原因是跨代引用的對(duì)象應(yīng)該傾向于同時(shí)生存或者同時(shí)死亡的(舉個(gè):如果某個(gè)新生代對(duì)象存在跨代引用,由于老年代對(duì)象難以消亡,該引用會(huì)使得新生代對(duì)象在收集時(shí)同樣得以存活,進(jìn)而在年齡增長(zhǎng)之后晉升到老年代中,這時(shí)跨代引用也隨即被消除了)。

依據(jù)上面說所,就不應(yīng)再為了少量的跨代引用去掃描整個(gè)老年代,也不必浪費(fèi)空間專門記錄每一個(gè)對(duì)象是否存在及存在哪些跨代引用,只需在新生代上建立一個(gè)全局的數(shù)據(jù)結(jié)構(gòu)(該結(jié)構(gòu)被稱為“記憶集”,Remembered Set),這個(gè)結(jié)構(gòu)把老年代劃分成若干小塊,標(biāo)識(shí)出老年代的哪一塊內(nèi)存會(huì)存在跨代引用。此后當(dāng)發(fā)生Minor GC時(shí),只有包含了跨代引用的小塊內(nèi)存里的對(duì)象才會(huì)被加入到GCRoots進(jìn)行掃描。雖然這種方法需要在對(duì)象改變引用關(guān)系(如將自己或者某個(gè)屬性賦值)時(shí)維護(hù)記錄數(shù)據(jù)的正確性,會(huì)增加一些運(yùn)行時(shí)的開銷,但比起收集時(shí)掃描整個(gè)老年代來說仍然是劃算的。

下面就來介紹一下這個(gè)全局的數(shù)據(jù)結(jié)構(gòu)記憶集。

記憶集

記憶集是一種用于記錄從非收集區(qū)域指向收集區(qū)域的指針集合的抽象數(shù)據(jù)結(jié)構(gòu)。如果我們不考慮效率和成本的話,最簡(jiǎn)單的實(shí)現(xiàn)可以用非收集區(qū)域中所有含跨代引用的對(duì)象數(shù)組來實(shí)現(xiàn)這個(gè)數(shù)據(jù)結(jié)構(gòu),如下面代碼所示:

//以對(duì)象指針來實(shí)現(xiàn)記憶集的偽代碼
Class RememberedSet {
	Object[] set[OBJECT_INTERGENERATIONAL_REFERENCE_SIZE]; 
}

這種記錄全部含跨代引用對(duì)象的實(shí)現(xiàn)方案,無論是空間占用還是維護(hù)成本都相當(dāng)高昂。而在垃圾收集的場(chǎng)景中,收集器只需要通過記憶集判斷出某一塊非收集區(qū)域是否存在有指向了收集區(qū)域的指針就可以了,并不需要了解這些跨代指針的全部細(xì)節(jié)。那設(shè)計(jì)者在實(shí)現(xiàn)記憶集的時(shí)候,便可以選擇更為粗獷的記錄粒度來節(jié)省記憶集的存儲(chǔ)和維護(hù)成本。下面列舉了一些可供選擇(當(dāng)然也可以選擇這個(gè)范圍以外的)的記錄精度:

  • 字長(zhǎng)精度:每個(gè)記錄精確到一個(gè)機(jī)器字長(zhǎng)(就是處理器的尋址位數(shù),如常見的32位或64位,這個(gè) 精度決定了機(jī)器訪問物理內(nèi)存地址的指針長(zhǎng)度),該字包含跨代指針。
  • 對(duì)象精度:每個(gè)記錄精確到一個(gè)對(duì)象,該對(duì)象里有字段含有跨代指針。
  • 卡精度:每個(gè)記錄精確到一塊內(nèi)存區(qū)域,該區(qū)域內(nèi)有對(duì)象含有跨代指針。

上面的,第三種“卡精度”所指的是用一種稱為“卡表”(Card Table)的方式去實(shí)現(xiàn)記憶集,這也是目前最常用的記憶集的實(shí)現(xiàn)形式。

卡表和記憶集又有什么關(guān)系呢?

前面介紹記憶集的時(shí)候提到 記憶集其實(shí)是一種"抽象”的數(shù)據(jù)結(jié)構(gòu),抽象的意思是只定義了記憶集的行為意圖,并沒有定義其行為的具體實(shí)現(xiàn)??ū砭褪怯洃浖囊环N具體實(shí)現(xiàn),它定義了記憶集的記錄精度、與堆內(nèi)存的映射關(guān)系等。關(guān)于記憶集與卡表的關(guān)系,可以按照J(rèn)ava中Map與HashMap的關(guān)系來類比理解(即接口和實(shí)現(xiàn)類來的關(guān)系)。

下面來詳細(xì)說一下記憶集的具體實(shí)現(xiàn)卡表

卡表

卡表是使用一個(gè)字節(jié)數(shù)組CARD_TABLE[] 實(shí)現(xiàn),每個(gè)元素對(duì)應(yīng)其標(biāo)識(shí)的內(nèi)存區(qū)域一塊特定大小的內(nèi)存塊,每個(gè)內(nèi)存塊稱為卡頁,hotspot使用的卡頁是2^9大小 即512字節(jié)。如下圖所示

這樣我們就可以把某個(gè)區(qū)域按照卡頁進(jìn)行劃分,假如我們現(xiàn)在要對(duì)新生代區(qū)域進(jìn)行垃圾回收,那么就可以把老年代區(qū)域看成是一個(gè)卡頁一個(gè)卡頁劃分好的,如下圖所示。

如圖所示,因?yàn)閏ardpage1中存在指向新生代的跨代引用,所以對(duì)應(yīng)卡表的第一個(gè)位置為1,表明該page區(qū)域存在跨代應(yīng)用的對(duì)象。

  • 卡表角度:因?yàn)閜age1中存在跨代飲用的對(duì)象,所以卡表對(duì)應(yīng)的第一個(gè)位置記為1,表明page1這個(gè)元素變臟。
  • 內(nèi)存回收角度:因?yàn)榭ū淼牡谝粋€(gè)位置為1,表明該page區(qū)域存在跨代應(yīng)用的對(duì)象,垃圾回收的時(shí)候需要掃描該區(qū)域。

一個(gè)卡頁的內(nèi)存中通常包含不止一個(gè)對(duì)象,只要卡頁內(nèi)有一個(gè)(或更多)對(duì)象的字段存在著跨代指針,那就將對(duì)應(yīng)卡表的數(shù)組元素的值標(biāo)識(shí)為1,稱為這個(gè)元素變臟(Dirty),沒有則標(biāo)識(shí)為0。在垃圾收集發(fā)生時(shí),只要篩選出卡表中變臟的元素,就能輕易得出哪些卡頁內(nèi)存塊中包含跨代指針,把它們加入GC Roots中一并掃描。這樣就不需要掃描整個(gè)老年代大大減少GC Roots的掃描范圍。 

到此這篇關(guān)于Java 萬字超詳細(xì)講解記憶集和卡表的文章就介紹到這了,更多相關(guān)Java 記憶集和卡表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA讀取文本文件內(nèi)容實(shí)例代碼

    JAVA讀取文本文件內(nèi)容實(shí)例代碼

    這篇文章主要給大家介紹了關(guān)于JAVA讀取文本文件內(nèi)容的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • MapReduce2框架的原理解析

    MapReduce2框架的原理解析

    這篇文章主要圍繞MapReduce2框架原理介紹的,文中有詳細(xì)的代碼示例,對(duì)學(xué)習(xí)有一定的幫助,需要的朋友可以借鑒參考
    2023-04-04
  • 希爾排序的算法代碼

    希爾排序的算法代碼

    希爾排序也是一種插入排序方法,實(shí)際上是一種分組插入方法。
    2013-03-03
  • springboot中.yml文件參數(shù)的讀取方式

    springboot中.yml文件參數(shù)的讀取方式

    這篇文章主要介紹了springboot中.yml文件參數(shù)的讀取方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • SpringBoot整合JPA數(shù)據(jù)源方法及配置解析

    SpringBoot整合JPA數(shù)據(jù)源方法及配置解析

    這篇文章主要介紹了SpringBoot整合JPA數(shù)據(jù)源方法及配置解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • SpringBoot中的classpath使用解讀

    SpringBoot中的classpath使用解讀

    本文詳細(xì)介紹了SpringBoot中的classpath及其在開發(fā)、編譯和打包過程中資源管理的方式,特別是在使用Maven構(gòu)建SpringBoot項(xiàng)目時(shí),資源文件如何從開發(fā)環(huán)境的resources目錄移動(dòng)到最終JAR包中的BOOT-INF/classes目錄,以及SpringBoot如何加載這些資源
    2025-02-02
  • SpringBoot配置HTTPS及開發(fā)調(diào)試的操作方法

    SpringBoot配置HTTPS及開發(fā)調(diào)試的操作方法

    在實(shí)際開發(fā)過程中,如果后端需要啟用https訪問,通常項(xiàng)目啟動(dòng)后配置nginx代理再配置https,前端調(diào)用時(shí)高版本的chrome還會(huì)因?yàn)樽C書未信任導(dǎo)致調(diào)用失敗,通過摸索整理一套開發(fā)調(diào)試下的https方案,下面給大家分享SpringBoot配置HTTPS及開發(fā)調(diào)試,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • IDEA中如何使用注解Test

    IDEA中如何使用注解Test

    這篇文章主要介紹了IDEA中如何使用注解Test問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 淺析Java中的繼承與組合

    淺析Java中的繼承與組合

    本文將介紹組合和繼承的概念及區(qū)別,并從多方面分析在寫代碼時(shí)如何進(jìn)行選擇。文中通過示例代碼介紹的很詳細(xì),有需要的朋友可以參考借鑒,下面來一起看看吧。
    2016-12-12
  • 一文詳解Spring?AOP的配置與使用

    一文詳解Spring?AOP的配置與使用

    面向切面編程(俗稱AOP)提供了一種面向?qū)ο缶幊?俗稱OOP)的補(bǔ)充,面向?qū)ο缶幊套詈诵牡膯卧穷?class),然而面向切面編程最核心的單元是切面(Aspects)。本文就來和大家聊聊AOP的配置與使用,感興趣的可以了解一下
    2022-11-11

最新評(píng)論

简阳市| 老河口市| 读书| 梨树县| 朝阳县| 刚察县| 江口县| 巴里| 抚州市| 龙川县| 九龙坡区| 沙坪坝区| 沈丘县| 奇台县| 河源市| 广东省| 大新县| 正阳县| 潍坊市| 腾冲县| 托克托县| 汾西县| 林西县| 申扎县| 区。| 泾阳县| 五华县| 光泽县| 滕州市| 玉龙| 治多县| 贵定县| 民乐县| 呈贡县| 永寿县| 南召县| 金山区| 沅陵县| 彭阳县| 西华县| 保亭|