二級java輔導(dǎo):有關(guān)于JVM的垃圾收集(二)

字號:

自適應(yīng)收集器
    在第一篇:有關(guān)于 JVM 的垃圾收集(一)  中談到過幾種垃圾收集的算法,然而我們的 JVM 啟動之后并不要求徹頭徹尾的死板的使用一種垃圾收集算法,固定的算法參數(shù)。因為某種情況下某些垃圾收集算法工作得更好,而別外一些收集算法在另外的情況下工作得更好,所以自適應(yīng)的垃圾收集技術(shù)應(yīng)運(yùn)而生。自適應(yīng)算法監(jiān)視堆中的情形,并且對應(yīng)的調(diào)整為合適的垃圾收集技術(shù)?;蚰苁菗Q一種垃圾收集算法,或者是調(diào)整當(dāng)前算法參數(shù),或者把堆劃分為子堆,同時在不同的子堆中使用不同的算法。
    簡述火車算法
    垃圾收集一般都會停止整個程序的運(yùn)行來查找和收集垃圾對象,它們可能在程序執(zhí)行的任意時刻暫停,并且暫停的時間也無法確定。垃圾收集也可能使得程序?qū)κ录憫?yīng)遲鈍,無法滿足實時系統(tǒng)的要求。如果一種垃圾收集算法可能導(dǎo)致用戶可察覺的到的停頓或者使得程序無法適合實時系統(tǒng)的要求,這種算法被稱作破壞性。垃圾收集算法的還有一個基本目標(biāo)是使本質(zhì)上的破壞性盡可能少,如果可能的話,盡可能消除這種破壞性。
    達(dá)到(或試圖達(dá)到) 非破壞性垃圾收集的方法是使用漸進(jìn)式收集算法。漸進(jìn)式收集器就是不試圖一次性發(fā)現(xiàn)并回收所有不可觸及的對象,而是每次發(fā)現(xiàn)并回收一部分。因為每次只有堆的一部分執(zhí)行垃圾收集,因此理論上說每次收集會持續(xù)更短的時間。保證這個最短時間接近某一個時長,就可以讓 Java 虛擬機(jī)適合實時環(huán)境,也就可以消除用戶可察覺的垃圾收集停頓,這可稱之為漸近時垃圾收集。
    漸進(jìn)式收集器通常是分代收集的,大部分調(diào)用中,都是收集堆的一部分。大部分對象都是*的,利用這一點,分代收集器在年幼子堆中比在年長子堆中更活躍。因為除了壽的子堆(成熟對象空間) 外,每個子堆中都可以給定一個尺寸,分代收集器大體上可以保證在一個時間內(nèi)漸進(jìn)地收集所有對象(壽的除外)。成熟對象空間無法給定尺寸,因為其中的對象不適合時沒個去處。
    于是針對成熟對象空間提供限定時間的漸時收集,Richard Hudson 和 Eliot Moss 提出了火車算法,目前正用于 Sun 公司的 Hotspot 虛擬機(jī)中。該算法詳細(xì)說明了分代收集的垃圾收集器的成熟對象空間的組織。大體有些車廂、火車、火車站的概念,對于該算法的此處不作進(jìn)一步說明了。
    finalize() 方法
    一個 Java 對象可以擁用終結(jié)方法:這個方法在垃圾收集器釋放對象之前必須運(yùn)行。但這么一個終結(jié)方法的引入并不明智,會使得 JVM 的垃圾收集的工作變得更得雜,所以別用它。
    因為,存在終結(jié)方法時,垃圾收集器必須在每次在收集時執(zhí)行一些額外的步驟。首先第一遍掃描時,垃圾收集器檢測出不再被引用的對象,然后看那些對象上是否聲明了終結(jié)方法,有則執(zhí)行。當(dāng)執(zhí)行了所有的終結(jié)方法后,垃圾收集器必須再次從根節(jié)點或是需要執(zhí)行終結(jié)的對象開始檢測不再被引用的對象,這稱作第二遍掃描。這個步驟是必要的,因為終結(jié)方法可能“復(fù)活”了第一遍掃描標(biāo)記的對象。最后,垃圾收集器才能釋放那些在第一遍和第二遍掃描中發(fā)現(xiàn)的都沒有被引用的對象。
    如果第一遍掃描標(biāo)記不再引用的對象的終結(jié)方法運(yùn)行過了,而后這個對象被自己或其他對象的終結(jié)方法復(fù)活了,稍后再次被收集時,執(zhí)行過的終結(jié)方法就不能再執(zhí)行了。同時終結(jié)方法何時被執(zhí)行也是無法預(yù)測的。