摘要:什么是復(fù)制算法復(fù)制算法是利用空間進(jìn)行分配的。另一方面,因?yàn)閺?fù)制算法只搜索并復(fù)制活動(dòng)對(duì)象,所以跟一般的標(biāo)記清除算法相比,它能在短時(shí)間內(nèi)完成,也就是說其吞吐量?jī)?yōu)秀。在復(fù)制算法中,每次運(yùn)行時(shí)都會(huì)執(zhí)行壓縮。
4 GC復(fù)制算法
??Copying GC是Marvin L.Minsky在1963年研究出來的算法。就是指把某個(gè)空間里的活動(dòng)對(duì)象復(fù)制到其它空間,把原空間里的所有對(duì)象都回收掉。在此,將復(fù)制活動(dòng)對(duì)象的原空間稱為From空間,將粘貼活動(dòng)對(duì)象的新空間稱為To空間。
4.1 什么是GC復(fù)制算法
??GC復(fù)制算法是利用From空間進(jìn)行分配的。當(dāng)From空間被完全占滿時(shí),GC會(huì)將活動(dòng)對(duì)象全部復(fù)制到To空間。當(dāng)復(fù)制完成后,該算法會(huì)把From空間和To空間互換,GC也就結(jié)束了。From空間和To空間大小必須一致。這是為了保證能把From空間中的所有活動(dòng)對(duì)象都收納到
4.1.1 執(zhí)行過程
假設(shè)目前堆里的配置如下。
??
執(zhí)行GC。首先是從根直接引用的對(duì)象B和G,B先被復(fù)制到了To空間。
將B被復(fù)制后生成的對(duì)象稱為B’。在From空間中B已經(jīng)被打上了復(fù)制完成標(biāo)簽。但是,這里只把B’復(fù)制了過來,它的子對(duì)象A還在From空間里,下面把A復(fù)制到To空間里。
??
這次才是真正意義上復(fù)制了B。因?yàn)锳沒有子對(duì)象,所以對(duì)A的復(fù)制就完成了。
接下來,要和復(fù)制B一樣從根引用復(fù)制G,以及其子對(duì)象E。雖然B也是G的子對(duì)象,不過因?yàn)橐呀?jīng)復(fù)制完B了,所以只要把從G執(zhí)行B的指針轉(zhuǎn)換到B’上。
最后,只要把From空間和To空間互換,GC就結(jié)束了。
對(duì)象C、D、F因?yàn)闆]法從根查找,所以會(huì)被回收。這里程序是以B、A、G、E的順序搜索對(duì)象的,使用的是深度優(yōu)先搜索。
4.2 優(yōu)點(diǎn)
4.2.1 優(yōu)秀的吞吐量
GC標(biāo)記-清除算法消耗的吞吐量是搜索活動(dòng)對(duì)象(標(biāo)記階段)所花費(fèi)的時(shí)間和搜索整體堆(清除階段)所花費(fèi)的時(shí)間之和。
另一方面,因?yàn)镚C復(fù)制算法只搜索并復(fù)制活動(dòng)對(duì)象,所以跟一般的GC標(biāo)記-清除算法相比,它能在短時(shí)間內(nèi)完成GC,也就是說其吞吐量?jī)?yōu)秀。
尤其是堆越大,差距越明顯。GC標(biāo)記-清除算法在清除階段所花費(fèi)的時(shí)間會(huì)不斷增加,但GC復(fù)制算法就不會(huì)。因?yàn)樗牡臅r(shí)間是與活動(dòng)對(duì)象的數(shù)量成比例的。
4.2.2 可實(shí)現(xiàn)高速分配
GC復(fù)制算法不使用空閑鏈表,因?yàn)榉謮K是一塊連續(xù)的內(nèi)存空間。因此,調(diào)查這個(gè)分塊的大小,只要這個(gè)分塊大小不小于所申請(qǐng)的大小,那么移動(dòng)指針就可以進(jìn)行分配了。
比起GC標(biāo)記-清除算法和引用計(jì)數(shù)算法等使用空閑鏈表的分配,GC復(fù)制算法明顯快得多。使用空閑鏈表是為了找到滿足要求的分塊,需要遍歷空閑鏈表,最壞的情況是我們不得不從空閑鏈表中取出最后一個(gè)分塊,這樣就用了大量時(shí)間把所有分塊都調(diào)查一遍。
4.2.3 不會(huì)發(fā)生碎片化
基于算法性質(zhì),活動(dòng)對(duì)象被集中安排在From空間的開頭。像這樣把對(duì)象重新集中,放在堆中一端的行為叫作壓縮。在GC復(fù)制算法中,每次運(yùn)行GC時(shí)都會(huì)執(zhí)行壓縮。
因此GC算法有個(gè)非常優(yōu)秀的特點(diǎn),就是不會(huì)發(fā)生碎片化,也就是說可以安排分塊允許范圍內(nèi)大小的對(duì)象。
另一方面,在GC標(biāo)記-清除算法等GC算法中,一旦安排了對(duì)象,原則上就不能再移動(dòng)它了,所以會(huì)多多少少產(chǎn)生碎片化。
4.2.4 與緩存兼容
在GC復(fù)制算法中有引用關(guān)系的對(duì)象會(huì)被安排在堆里離彼此較近的位置。B’引用A’,G’引用E’的順序排列。這種情況有一個(gè)優(yōu)點(diǎn),那就是mutator執(zhí)行速度極快。很多CPU都通過緩存來來高速讀取位置較近的對(duì)象。這也是借助壓縮來完成的,通過壓縮來把有引用關(guān)系的對(duì)象安排在堆中較近的位置。
4.3 缺點(diǎn)
4.3.1 堆使用率低下
GC復(fù)制算法把堆分成二等分,通常只能利用其中一半來安排對(duì)象。也就是說只有一半堆能被使用,相比其他能使用整個(gè)堆的GC算法而言,這是GC復(fù)制算法的一個(gè)重大缺陷。
4.3.2 不兼容保守式GC算法
GC標(biāo)記-清除算法有著跟保守式GC算法相兼容的優(yōu)點(diǎn)。因?yàn)镚C標(biāo)記-清除算法不用移動(dòng)對(duì)象。
另一方面,GC復(fù)制算法必須移動(dòng)對(duì)象重寫指針,所以有著跟保守式GC算法不相容的性質(zhì)。雖然有限制條件,GC復(fù)制算法和保守式GC算法可以進(jìn)行組合。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/71535.html
摘要:在運(yùn)行腳本時(shí),需要顯示的指定對(duì)象。大對(duì)象區(qū)每一個(gè)區(qū)域都是由一組內(nèi)存頁(yè)構(gòu)成的。這里是唯一擁有執(zhí)行權(quán)限的內(nèi)存區(qū)。換句話說,是該對(duì)象被之后所能回收到內(nèi)存的總和。一旦活躍對(duì)象已被移出,則在舊的半空間中剩下的任何死亡對(duì)象被丟棄。 內(nèi)存管理 本文以V8為背景 對(duì)之前的文章進(jìn)行重新編輯,內(nèi)容做了很多的調(diào)整,使其具有邏輯更加緊湊,內(nèi)容更加全面。 1. 基礎(chǔ)概念 1.1 生命周期 不管什么程序語(yǔ)言,內(nèi)存...
摘要:主要在堆上分配內(nèi)存,而堆又分為新生代和老年代兩個(gè)部分,新生代又再分為區(qū)和區(qū)兩部分,本文根據(jù)堆的劃分,描述的內(nèi)存分配策略。 java主要在堆上分配內(nèi)存,而Java堆又分為新生代(YoungGen)和老年代(OldGen)兩個(gè)部分,新生代又再分為Eden區(qū)和Survivor區(qū)兩部分,本文根據(jù)java堆的劃分,描述hotspot的內(nèi)存分配策略。 showImg(https://segme...
摘要:的字節(jié)碼解釋器和編譯器使用寫屏障維護(hù)卡表。解釋器每次執(zhí)行更新引用的字節(jié)碼時(shí),都會(huì)執(zhí)行一段寫屏障,編譯器在生成更新引用的代碼后,也會(huì)生成一段寫屏障。 4. JVM 4.1 GC 1. 垃圾收集 基礎(chǔ) : 可達(dá)性分析算法 GC ROOTS 復(fù)制算法 標(biāo)記清除 標(biāo)記整理 分代收集 -- 1. 新生代 ; 2.3 老年代注: Oop Map -- 安全點(diǎn) -- 安全區(qū) 以下部分內(nèi)容 來自 ...
摘要:垃圾回收及一次內(nèi)存泄漏處理內(nèi)存分布上圖展示了的架構(gòu)圖,本篇我們主要關(guān)注,運(yùn)行時(shí)數(shù)據(jù)區(qū)。但是垃圾回收并不能百分百保證不會(huì)出現(xiàn)內(nèi)存泄漏,所以了解垃圾回收,對(duì)于我們遇到內(nèi)存泄漏時(shí)能更加清晰的分析原因,也能幫助我們寫出更加安全,可靠的程序。 [toc] JAVA GC垃圾回收(及一次內(nèi)存泄漏處理) showImg(https://segmentfault.com/img/remote/1460...
閱讀 610·2021-10-08 10:20
閱讀 1496·2021-09-23 11:22
閱讀 3229·2019-08-30 15:55
閱讀 1617·2019-08-28 18:25
閱讀 1872·2019-08-28 18:14
閱讀 1245·2019-08-26 11:37
閱讀 2907·2019-08-26 10:18
閱讀 2433·2019-08-23 18:39