資源描述:
《【深入java虛擬機(jī)(8)】:java垃圾收集機(jī)制-編程開(kāi)發(fā)技術(shù)》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫(kù)。
1、【深入Java虛擬機(jī)(8)】:Java垃圾收集機(jī)制-編程開(kāi)發(fā)技術(shù)【深入Java虛擬機(jī)(8)】:Java垃圾收集機(jī)制原文出處:蘭亭風(fēng)雨對(duì)象引用Java中的垃圾回收一般是在Java堆中進(jìn)行,因?yàn)槎阎袔缀醮娣帕薐ava中所有的對(duì)象實(shí)例。談到Java堆中的垃圾冋收,自然要談到引用。在JDK1.2之前,Java小的引用定義很很純粹:如果reference類(lèi)型的數(shù)據(jù)屮存儲(chǔ)的數(shù)值代表的是另外一塊內(nèi)存的起始地址,就稱(chēng)這塊內(nèi)存代表著一個(gè)引用。但在JDK1.2之后,Java對(duì)引用的概念進(jìn)行了擴(kuò)充,將其分為強(qiáng)引用(Strong?Reference)、軟引
2、用(Soft?Reference)、弱引用(Weak?Reference)、虛引用(Phantom?Reference)四種,引用強(qiáng)度依次減弱。?強(qiáng)引用:如“Objcct?obj?二?new?Object()”,這類(lèi)引用是Java程序中最普遍的。只要強(qiáng)引用還存在,垃圾收集器就永遠(yuǎn)不會(huì)回收掉被引用的對(duì)彖。?軟引用:它用來(lái)描述一些可能還有用,但并非必須的對(duì)象。在系統(tǒng)內(nèi)存不夠用時(shí),這類(lèi)引川關(guān)聯(lián)的對(duì)象將被垃圾收集器回收oJDKl.2之后捉供了SoftReference類(lèi)來(lái)實(shí)現(xiàn)軟引用。?弱引用:它也是用來(lái)描述非需對(duì)象的,但它的強(qiáng)度比軟引用更弱
3、些,被弱引用關(guān)聯(lián)的對(duì)象只能生存島下一次垃圾收集發(fā)生Z前。當(dāng)垃圾收集器工作吋,無(wú)論當(dāng)前內(nèi)存是否足夠,都會(huì)回收掉只被弱引用關(guān)聯(lián)的對(duì)象。在JDK1.2之后,提供了WeakReference類(lèi)來(lái)實(shí)現(xiàn)弱引用。?虛引用:最弱的一種引用關(guān)系,完全不會(huì)對(duì)其生存時(shí)間構(gòu)成影響,也無(wú)法通過(guò)虛引用來(lái)取得一個(gè)對(duì)象實(shí)例。為一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一II的是希望能在這個(gè)對(duì)象被收集器回收時(shí)收到一個(gè)系統(tǒng)通知。JDK1.2Z后提供了PhantomReference類(lèi)來(lái)實(shí)現(xiàn)虛引用。垃圾對(duì)象的判定Java堆小存放著幾乎所有的對(duì)象實(shí)例,垃圾收集器對(duì)堆小的對(duì)彖進(jìn)行回收前,要
4、先確定這些對(duì)象是否還有用,判定對(duì)象是否為垃圾對(duì)象有如下算法:??引用計(jì)數(shù)算法給對(duì)象添加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)地方引用它時(shí),計(jì)數(shù)器值就加1,當(dāng)引用失效時(shí),計(jì)數(shù)器值就減I,任何時(shí)刻計(jì)數(shù)器都為0的對(duì)彖就是不可能再被使用的。引用計(jì)數(shù)算法的實(shí)現(xiàn)簡(jiǎn)單,判定效率也很高,在人部分情況下它都是一個(gè)不錯(cuò)的選擇,當(dāng)Ja腹語(yǔ)言并沒(méi)有選擇這種算法來(lái)進(jìn)行垃圾冋收,主要原因是它很難解決對(duì)彖之間的相互循環(huán)引用問(wèn)題。???根搜索算法Java和C#小都是采用根搜索算法來(lái)判定對(duì)象是否存活的。這種算法的基木思路是通過(guò)一系列名為“GC?Roots”的對(duì)象作為起始點(diǎn),從這
5、些節(jié)點(diǎn)開(kāi)始向下搜索,搜索所走過(guò)的路徑稱(chēng)為引用鏈,當(dāng)一個(gè)對(duì)象到GC?Roots沒(méi)有任何引用鏈相連時(shí),就證明此對(duì)象是不可用的。在Java語(yǔ)言里,可作為GC?Roots的兌現(xiàn)包括下而幾種:?虛擬機(jī)棧(棧幀中的本地變量表)中引用的對(duì)彖。?方法區(qū)中的類(lèi)靜態(tài)屬性引用的對(duì)象。?方法區(qū)小的常量引用的對(duì)象。?本地方法棧中JNI(Native方法)的引用對(duì)象。實(shí)際上,在根搜索算法中,要真正宣告一個(gè)對(duì)象死亡,至少要經(jīng)歷兩次標(biāo)記過(guò)程:如果對(duì)象在進(jìn)行根搜索后發(fā)現(xiàn)沒(méi)有與GC?Roots相連接的引用鏈,那它會(huì)被第一次標(biāo)記并11進(jìn)行一次篩選,篩選的條件是此對(duì)象是否
6、有必要執(zhí)行()方法。當(dāng)對(duì)象沒(méi)有覆蓋finalize()方法,或finalize()方法已經(jīng)被虛擬機(jī)調(diào)用過(guò),虛擬機(jī)將這兩種情況都視為沒(méi)冇必耍執(zhí)行。如果該對(duì)彖被判定為冇必要執(zhí)行finalize()方法,那么這個(gè)對(duì)彖將會(huì)被放置在一個(gè)名為F-Queue隊(duì)列中,并在稍后由一條由虛擬機(jī)自動(dòng)建立的、低優(yōu)先級(jí)的Finalizer線程去執(zhí)行finalize()方法。finalize()方法是對(duì)象逃脫死亡命運(yùn)的最后一次機(jī)會(huì)(因?yàn)橐粋€(gè)對(duì)象的finalizc()方法最多只會(huì)被系統(tǒng)口動(dòng)調(diào)用一次),稍后GC將對(duì)F-Queue屮的對(duì)彖進(jìn)行第二次小規(guī)模的標(biāo)記,如杲
7、要在finalize()方法屮成功拯救口己,只要在finalize()方法中讓該對(duì)象重引用鏈上的任何一個(gè)對(duì)象建立關(guān)聯(lián)即可。而如果對(duì)象這吋還沒(méi)有關(guān)聯(lián)到任何鏈上的引用,那它就會(huì)被冋收掉。垃圾收集算法判定除了垃圾對(duì)象之后,便可以進(jìn)行垃圾回收了。下面介紹一些垃圾收集算法,由于垃圾收集算法的實(shí)現(xiàn)涉及大量的程序細(xì)節(jié),因此這里主要是闡明各算法的實(shí)現(xiàn)思想,而不去細(xì)論算法的具體實(shí)現(xiàn)。???標(biāo)記一清除算法標(biāo)記一清除算法是最基礎(chǔ)的收集算法,它分為“標(biāo)記”和“清除”兩個(gè)階段:首先標(biāo)記出所需回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收掉所冇被標(biāo)記的對(duì)彖,它的標(biāo)記過(guò)程其實(shí)
8、就是前面的根搜索算法中判定垃圾對(duì)彖的標(biāo)記過(guò)程。標(biāo)記一清除算法的執(zhí)行情況如下圖所示:冋收前狀態(tài):存活對(duì)象可回收未使用??回收后狀態(tài):該算法有如下缺點(diǎn):?標(biāo)記和清除過(guò)程的效率都不高。?標(biāo)記清除后會(huì)產(chǎn)生人量不連續(xù)的內(nèi)存碎片,空間碎片太多可能