摘要:現(xiàn)在,通過(guò)對(duì)這三種方式進(jìn)行融合,出現(xiàn)了一些更加高級(jí)的方式。這樣一來(lái),需要掃描的對(duì)象數(shù)量就會(huì)大幅減少。像這樣以全部區(qū)域?yàn)閷?duì)象的操作被稱為完全回收或者大回收。在一般的算法中,作出這樣的保證是不可能的,因?yàn)楫a(chǎn)生的中斷時(shí)間與對(duì)象的數(shù)量和狀態(tài)有關(guān)。
jvm系列
垃圾回收基礎(chǔ)
JVM的編譯策略
GC的三大基礎(chǔ)算法
GC的三大高級(jí)算法
GC策略的評(píng)價(jià)指標(biāo)
JVM信息查看
GC通用日志解讀
jvm的card table數(shù)據(jù)結(jié)構(gòu)
Java類初始化順序
Java對(duì)象結(jié)構(gòu)及大小計(jì)算
Java的類加載機(jī)制
Java對(duì)象分配簡(jiǎn)要流程
年老代過(guò)大有什么影響
Survivor空間溢出實(shí)例
關(guān)于Object=null
Java線程與Xss
序GC的基本算法,大體上都逃不出標(biāo)記清除法/標(biāo)記壓縮法、復(fù)制收集算法、引用計(jì)數(shù)法這三種方式以及它們的衍生品?,F(xiàn)在,通過(guò)對(duì)這三種方式進(jìn)行融合,出現(xiàn)了一些更加高級(jí)的方式。這里,我們介紹一下其中最有代表性的三種,即分代回收、增量回收和并行回收。有些情況下,也可以對(duì)這些方法中的幾種進(jìn)行組合使用。
1、分代回收首先,我們來(lái)講講高級(jí)GC技術(shù)中最重要的一種,即分代回收(Generational GC)。由于GC和程序處理的本質(zhì)是無(wú)關(guān)的,因此它所消耗的時(shí)間越短越好。分代回收的目的,正是為了在程序運(yùn)行期間,將GC所消耗的時(shí)間盡量縮短。分代回收的基本思路,是利用了一般性程序所具備的性質(zhì),即大部分對(duì)象都會(huì)在短時(shí)間內(nèi)成為垃圾,而經(jīng)過(guò)一定時(shí)間依然存活的對(duì)象往往擁有較長(zhǎng)的壽命。如果壽命長(zhǎng)的對(duì)象更容易存活下來(lái),壽命短的對(duì)象則會(huì)被很快廢棄,那么到底怎樣做才能讓GC變得更加高效呢?如果對(duì)分配不久,誕生時(shí)間較短的“年輕”對(duì)象進(jìn)行重點(diǎn)掃描,應(yīng)該就可以更有效地回收大部分垃圾。
在分代回收中,對(duì)象按照生成時(shí)間進(jìn)行分代,剛剛生成不久的年輕對(duì)象劃為新生代(Young gen-eration),而存活了較長(zhǎng)時(shí)間的對(duì)象劃為老生代(Old generation)。根據(jù)具體實(shí)現(xiàn)方式的不同,可能還會(huì)劃分更多的代,在這里為了講解方便,我們就先限定為兩代。如果上述關(guān)于對(duì)象壽命的假說(shuō)成立的話,那么只要僅僅掃描新生代對(duì)象,就可以回收掉廢棄對(duì)象中的很大一部分。像這種只掃描新生代對(duì)象的回收操作,被稱為小回收(Minor GC)。小回收的具體回收步驟如下。首先從根開(kāi)始一次常規(guī)掃描,找到“存活”對(duì)象。這個(gè)步驟采用標(biāo)記清除或者是復(fù)制收集算法都可以,不過(guò)大多數(shù)分代回收的實(shí)現(xiàn)都采用了復(fù)制收集算法。需要注意的是,在掃描的過(guò)程中,如果遇到屬于老生代的對(duì)象,則不對(duì)該對(duì)象繼續(xù)進(jìn)行遞歸掃描。這樣一來(lái),需要掃描的對(duì)象數(shù)量就會(huì)大幅減少。然后,將第一次掃描后殘留下來(lái)的對(duì)象劃分到老生代。具體來(lái)說(shuō),如果是用復(fù)制收集算法的話,只要將復(fù)制目標(biāo)空間設(shè)置為老生代就可以了;而用標(biāo)記清除算法的話,則大多采用在對(duì)象上設(shè)置某種標(biāo)志的方式。
從任何地方都沒(méi)有進(jìn)行引用的老生代中的F對(duì)象,會(huì)通過(guò)大回收操作進(jìn)行回收。
對(duì)來(lái)自老生代的引用進(jìn)行記錄這個(gè)時(shí)候,問(wèn)題出現(xiàn)了,從老生代對(duì)象對(duì)新生代對(duì)象的引用怎么辦呢?如果只掃描新生代區(qū)域的話,那么從老生代對(duì)新生代的引用就不會(huì)被檢測(cè)到。這樣一來(lái),如果一個(gè)年輕的對(duì)象只有來(lái)自老生代對(duì)象的引用,就會(huì)被誤認(rèn)為已經(jīng)“死亡”了。因此,在分代回收中,會(huì)對(duì)對(duì)象的更新進(jìn)行監(jiān)視,將從老生代對(duì)新生代的引用,記錄在一個(gè)叫做記錄集(remembered set)的表中(圖5)。在執(zhí)行小回收的過(guò)程中,這個(gè)記錄集也作為一個(gè)根來(lái)對(duì)待。
要讓分代回收正確工作,必須使記錄集的內(nèi)容保持更新。為此,在老生代到新生代的引用產(chǎn)生的瞬間,就必須對(duì)該引用進(jìn)行記錄,而負(fù)責(zé)執(zhí)行這個(gè)操作的子程序,需要被嵌入到所有涉及對(duì)象更新操作的地方。這個(gè)負(fù)責(zé)記錄引用的子程序是這樣工作的。設(shè)有兩個(gè)對(duì)象:A和B,當(dāng)對(duì)A的內(nèi)容進(jìn)行改寫(xiě),并加入對(duì)B的引用時(shí),如果①A屬于老生代對(duì)象,②B屬于新生代對(duì)象,則將該引用添加到記錄集中。這種檢查程序需要對(duì)所有涉及修改對(duì)象內(nèi)容的地方進(jìn)行保護(hù),因此被稱為寫(xiě)屏障(Write barrier)。寫(xiě)屏障不僅用于分代回收,同時(shí)也用在很多其他的GC算法中。雖說(shuō)老生代區(qū)域中的對(duì)象一般來(lái)說(shuō)壽命都比較長(zhǎng),但也決不是“不老不死”的。隨著程序的運(yùn)行,老生代區(qū)域中的“死亡”對(duì)象也在不斷增加。為了避免這些死亡的老生代對(duì)象白白占用內(nèi)存空間,偶爾需要對(duì)包括老生代區(qū)域在內(nèi)的全部區(qū)域進(jìn)行一次掃描回收。像這樣以全部區(qū)域?yàn)閷?duì)象的GC操作被稱為完全回收(Full GC)或者大回收(Major GC)。分代回收通過(guò)減少GC中掃描的對(duì)象數(shù)量,達(dá)到縮短GC帶來(lái)的平均中斷時(shí)間的效果。不過(guò)由于還是需要進(jìn)行大回收,因此最大中斷時(shí)間并沒(méi)有得到什么改善。從吞吐量來(lái)看,在對(duì)象壽命假說(shuō)能夠成立的程序中,由于掃描對(duì)象數(shù)量的減少,可以達(dá)到非常不錯(cuò)的成績(jī)。但是,其性能會(huì)被程序行為、分代數(shù)量、大回收觸發(fā)條件等因素大幅度左右。
2、增量回收在對(duì)實(shí)時(shí)性要求很高的程序中,比起縮短GC的平均中斷時(shí)間,往往更重視縮短GC的最大中斷時(shí)間。例如,在機(jī)器人的姿勢(shì)控制程序中,如果因?yàn)镚C而讓控制程序中斷了0.1秒,機(jī)器人可能就摔倒了?;蛘撸绻囕v制動(dòng)控制程序因?yàn)镚C而延遲響應(yīng)的話,后果也是不堪設(shè)想的。在這些對(duì)實(shí)時(shí)性要求很高的程序中,必須能夠?qū)C所產(chǎn)生的中斷時(shí)間做出預(yù)測(cè)。例如,可以將“最多只能中斷10毫秒”作為附加條件。在一般的GC算法中,作出這樣的保證是不可能的,因?yàn)镚C產(chǎn)生的中斷時(shí)間與對(duì)象的數(shù)量和狀態(tài)有關(guān)。
因此,為了維持程序的實(shí)時(shí)性,不等到GC全部完成,而是將GC操作細(xì)分成多個(gè)部分逐一執(zhí)行。這種方式被稱為增量回收(Incremental GC)。在增量回收中,由于GC過(guò)程是漸進(jìn)的,在回收過(guò)程中程序本身會(huì)繼續(xù)運(yùn)行,對(duì)象之間的引用關(guān)系也可能會(huì)發(fā)生變化。如果已經(jīng)完成掃描和標(biāo)記的對(duì)象被修改,對(duì)新的對(duì)象產(chǎn)生了引用,這個(gè)新對(duì)象就不會(huì)被標(biāo)記,明明是“存活”對(duì)象卻被回收掉了。在增量回收中為了避免這樣的問(wèn)題,和分代回收一樣也采用了寫(xiě)屏障。當(dāng)已經(jīng)被標(biāo)記的對(duì)象的引用關(guān)系發(fā)生變化時(shí),通過(guò)寫(xiě)屏障會(huì)將新被引用的對(duì)象作為掃描的起始點(diǎn)記錄下來(lái)。由于增量回收的過(guò)程是分步漸進(jìn)式的,可以將中斷時(shí)間控制在一定長(zhǎng)度之內(nèi)。另一方面,由于中斷操作需要消耗一定的時(shí)間,GC所消耗的總時(shí)間就會(huì)相應(yīng)增加,正所謂有得必有失。
3、并行回收最近的計(jì)算機(jī)中,一塊芯片上搭載多個(gè)CPU核心的多核處理器已經(jīng)逐漸普及。不僅是服務(wù)器,就連個(gè)人桌面電腦中,多核CPU也已經(jīng)成了家常便飯。例如美國(guó)英特爾公司的Core i7就擁有6核12個(gè)線程。在這樣的環(huán)境中,就需要通過(guò)利用多線程來(lái)充分發(fā)揮多CPU的性能。并行回收正是通過(guò)最大限度利用多CPU的處理能力來(lái)進(jìn)行GC操作的一種方式。并行回收的基本原理是,是在原有的程序運(yùn)行的同時(shí)進(jìn)行GC操作,這一點(diǎn)和增量回收是相似的。不過(guò),相對(duì)于在一個(gè)CPU上進(jìn)行GC任務(wù)分割的增量回收來(lái)說(shuō),并行回收可以利用多CPU的性能,盡可能讓這些GC任務(wù)并行(同時(shí))進(jìn)行。由于軟件運(yùn)行和GC操作是同時(shí)進(jìn)行的,因此就會(huì)遇到和增量回收相同的問(wèn)題。為了解決這個(gè)問(wèn)題,并行回收也需要用寫(xiě)屏障來(lái)對(duì)當(dāng)前的狀態(tài)信息保持更新。不過(guò),讓GC操作完全并行,而一點(diǎn)都不影響原有程序的運(yùn)行,是做不到的。因此在GC操作的某些特定階段,還是需要暫停原有程序的運(yùn)行。在多核化快速發(fā)展的現(xiàn)在,并行回收也成了一個(gè)非常重要的話題,它的算法也在不斷進(jìn)行改善。在硬件系統(tǒng)的支持下,無(wú)需中斷原有程序的完全并行回收器也已經(jīng)呼之欲出。今后,這個(gè)領(lǐng)域相當(dāng)值得期待。
引用代碼的未來(lái)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/65634.html
摘要:它的基本原理是,在每個(gè)對(duì)象中保存該對(duì)象的引用計(jì)數(shù),當(dāng)引用發(fā)生增減時(shí)對(duì)計(jì)數(shù)進(jìn)行更新。實(shí)現(xiàn)容易是引用計(jì)數(shù)算法最大的優(yōu)點(diǎn)。引用計(jì)數(shù)最大的缺點(diǎn),就是無(wú)法釋放循環(huán)引用的對(duì)象。為了避免這種情況的發(fā)生,對(duì)引用計(jì)數(shù)的操作必須采用獨(dú)占的方式來(lái)進(jìn)行。 jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級(jí)算法 GC策略的評(píng)價(jià)指標(biāo) JVM信息查看 GC通用日志解讀 jvm的card...
摘要:系統(tǒng)總運(yùn)行時(shí)間應(yīng)用程序耗時(shí)耗時(shí)。一般而言,頻率越低越好,通常增大堆空間可以有效降低垃圾回收發(fā)生的頻率,但是會(huì)增加回收時(shí)產(chǎn)生的停頓時(shí)間。反應(yīng)時(shí)間當(dāng)一個(gè)對(duì)象成為垃圾后,多長(zhǎng)時(shí)間內(nèi),它所占用的內(nèi)存空間會(huì)被釋放掉。 jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級(jí)算法 GC策略的評(píng)價(jià)指標(biāo) JVM信息查看 GC通用日志解讀 jvm的card table數(shù)據(jù)結(jié)構(gòu) J...
摘要:在一般應(yīng)用中,不會(huì)逃逸的局部對(duì)象所占的比例很大,如果能使用棧上分配,那大量的對(duì)象就會(huì)隨著方法的結(jié)束而自動(dòng)銷毀了,垃圾收集系統(tǒng)的壓力將會(huì)小很多。相關(guān)參數(shù)設(shè)置大對(duì)象直接進(jìn)入年老代的閾值,當(dāng)對(duì)象大小超過(guò)這個(gè)值時(shí),將直接在年老代分配。 jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級(jí)算法 GC策略的評(píng)價(jià)指標(biāo) JVM信息查看 GC通用日志解讀 jvm的card t...
摘要:系列垃圾回收基礎(chǔ)的編譯策略的三大基礎(chǔ)算法的三大高級(jí)算法策略的評(píng)價(jià)指標(biāo)信息查看通用日志解讀的數(shù)據(jù)結(jié)構(gòu)類初始化順序?qū)ο蠼Y(jié)構(gòu)及大小計(jì)算的類加載機(jī)制對(duì)象分配簡(jiǎn)要流程年老代過(guò)大有什么影響空間溢出實(shí)例關(guān)于線程與序本文主要講述如何查看應(yīng)用的信息。 jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級(jí)算法 GC策略的評(píng)價(jià)指標(biāo) JVM信息查看 GC通用日志解讀 jvm的car...
摘要:系列垃圾回收基礎(chǔ)的編譯策略的三大基礎(chǔ)算法的三大高級(jí)算法策略的評(píng)價(jià)指標(biāo)信息查看通用日志解讀的數(shù)據(jù)結(jié)構(gòu)類初始化順序?qū)ο蠼Y(jié)構(gòu)及大小計(jì)算的類加載機(jī)制對(duì)象分配簡(jiǎn)要流程年老代過(guò)大有什么影響空間溢出實(shí)例關(guān)于線程與序本文主要講述日志的解讀。 jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級(jí)算法 GC策略的評(píng)價(jià)指標(biāo) JVM信息查看 GC通用日志解讀 jvm的card ta...
閱讀 820·2023-04-25 20:18
閱讀 2104·2021-11-22 13:54
閱讀 2547·2021-09-26 09:55
閱讀 3912·2021-09-22 15:28
閱讀 2982·2021-09-03 10:34
閱讀 1719·2021-07-28 00:15
閱讀 1645·2019-08-30 14:25
閱讀 1289·2019-08-29 17:16