判斷Java對(duì)象是否存活的算法

聲明:本文摘抄自《深入理解Java虛擬機(jī)》一書,本文完全為自我學(xué)習(xí)残揉,請(qǐng)感興趣的同學(xué)購(gòu)買正版奶赔,支持原創(chuàng)

判斷對(duì)象是否存活的算法包括:

  1. 引用計(jì)數(shù)算法
  2. 可達(dá)性分析算法

引用計(jì)數(shù)算法(Reference Counting)

給對(duì)象中添加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)地方引用它時(shí)镀赌,計(jì)數(shù)器加1音念;當(dāng)引用失效時(shí)沪饺,計(jì)數(shù)器值減1;任何時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不能再被引用的闷愤。例如Object-C整葡,Python語(yǔ)音使用引用計(jì)數(shù)算法進(jìn)行內(nèi)存管理。Java虛擬機(jī)沒(méi)有選用引用計(jì)數(shù)器算法來(lái)管理內(nèi)存讥脐,其中最主要的原有是它很難解決對(duì)象之間相互循環(huán)引用的問(wèn)題遭居。

對(duì)象循環(huán)引用代碼示例:

public class ReferenceCountingGC {
    public Object instance = null;
    
    public static void testGC() {
        ReferenceCountingGC objA = new ReferenceCountingGC();
        ReferenceCountingGC objB = new ReferenceCountingGC();
        objA.instance = objB;
        objB.instance = objA;
        
        objA = null;
        objB = null;
        
        // 假設(shè)在這行發(fā)生GC, objA 和 objB是否能被回收旬渠?
        System.gc();
    }
}

對(duì)象objA和objB都有字段instance俱萍,賦值令 objA.instance = objB及objB.instance = objA,除此之外告丢,這兩個(gè)對(duì)象再無(wú)任務(wù)引用枪蘑,實(shí)際上這兩個(gè)對(duì)象已經(jīng)不可能再被訪問(wèn),但是它們因?yàn)橄嗷ヒ弥鴮?duì)方岖免,導(dǎo)致它們的引用計(jì)數(shù)都不為0岳颇,于是引用計(jì)數(shù)算法無(wú)法通知GC收集器回收它們。

可達(dá)性分析算法(Reachability Analysis)

可達(dá)性分析算法的基本思路是通過(guò)一系列的稱為“GC Roots”的對(duì)象作為起始點(diǎn)觅捆,從這些節(jié)點(diǎn)開始向下搜索赦役,搜索所走過(guò)的路徑稱為引用鏈(Reference Chain)麻敌,當(dāng)一個(gè)對(duì)象到GC Root沒(méi)有任何引用鏈相連時(shí)栅炒,則證明此對(duì)象是不可用的。

左側(cè)為仍然存活的對(duì)象,右側(cè)為可回收的對(duì)象

生成還是死亡

即使在可達(dá)性分析算法中不可達(dá)的對(duì)象赢赊,也并非是“非死不可”的乙漓,這時(shí)候它們暫時(shí)處于“緩刑”階段,要真正宣告一個(gè)對(duì)象死亡释移,至少要經(jīng)歷兩次標(biāo)記過(guò)程:如果對(duì)象在進(jìn)行可達(dá)性分析后發(fā)現(xiàn)沒(méi)有與GC Roots相連接的引用叭披,那它將會(huì)被第一次標(biāo)記并且進(jìn)行一次篩選,篩選的條件是此對(duì)象是否是否有必要執(zhí)行finalize()方法玩讳。當(dāng)對(duì)象沒(méi)有覆蓋finalize()方法涩蜘,或者finalize()方法已經(jīng)被虛擬機(jī)調(diào)用過(guò),虛擬機(jī)將這兩種情況都視為“沒(méi)有必要執(zhí)行”熏纯。
??如果這個(gè)對(duì)象被判定為有必要執(zhí)行finalize()方法同诫,那么這個(gè)對(duì)象將會(huì)放置在一個(gè)叫做F-Queue的隊(duì)列之中。并在稍后由一個(gè)虛擬機(jī)自動(dòng)建立的樟澜,低優(yōu)先級(jí)的Finalizer線程去執(zhí)行它误窖。這里所謂“執(zhí)行”是指虛擬機(jī)會(huì)觸發(fā)這個(gè)方法,但并不承諾會(huì)等待它運(yùn)行結(jié)束秩贰,這樣做的原有是霹俺,如果有一個(gè)對(duì)象在finalize()方法中執(zhí)行緩慢,或者發(fā)生死循環(huán)毒费,將可能會(huì)導(dǎo)致F-Queue隊(duì)列中其他對(duì)象永久處于等待丙唧,甚至導(dǎo)致整個(gè)內(nèi)存回收系統(tǒng)崩潰。
??finalize()方法是對(duì)象逃脫死亡命運(yùn)的最后一次機(jī)會(huì)觅玻,稍后GC將對(duì)F-Queue中的對(duì)象進(jìn)行第二次小規(guī)模的標(biāo)記艇棕,如果對(duì)象這個(gè)時(shí)候,未被重新引用串塑,那它基本上就真的被回收了沼琉。

回收方法區(qū)

Java虛擬機(jī)規(guī)范中確實(shí)說(shuō)過(guò)可以不要求虛擬機(jī)在方法區(qū)中實(shí)現(xiàn)垃圾回收,而且在方法區(qū)中進(jìn)行垃圾回收的“性價(jià)比”一般比較低桩匪,方法區(qū)的垃圾收集主要回收兩部分內(nèi)容:廢棄的常量和無(wú)用的類打瘪。

廢棄的常量,以常量池中字面量的回收為例傻昙,假如一個(gè)字符串“abc”已經(jīng)進(jìn)入常量池中闺骚,但是當(dāng)前系統(tǒng)已經(jīng)沒(méi)有任何一個(gè)String對(duì)象叫做“abc”的,也沒(méi)有任何其他地方引用這個(gè)字面量妆档,這個(gè)“abc”常量就會(huì)被清理出常量池僻爽。

判斷一個(gè)無(wú)用的類需要同時(shí)滿足下面3個(gè)條件才能算是“無(wú)用的類”

  • 該類的所有實(shí)例都已經(jīng)被回收
  • 加載該類的ClassLoader已經(jīng)被回收
  • 該類對(duì)應(yīng)的java.lang.Class對(duì)象已經(jīng)沒(méi)有任何地方被引用,無(wú)法在任何地方通過(guò)反射訪問(wèn)該類的方法贾惦。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末胸梆,一起剝皮案震驚了整個(gè)濱河市敦捧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碰镜,老刑警劉巖兢卵,帶你破解...
    沈念sama閱讀 223,002評(píng)論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異绪颖,居然都是意外死亡秽荤,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門柠横,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)窃款,“玉大人,你說(shuō)我怎么就攤上這事牍氛⊙阆纾” “怎么了?”我有些...
    開封第一講書人閱讀 169,787評(píng)論 0 365
  • 文/不壞的土叔 我叫張陵糜俗,是天一觀的道長(zhǎng)踱稍。 經(jīng)常有香客問(wèn)我,道長(zhǎng)悠抹,這世上最難降的妖魔是什么珠月? 我笑而不...
    開封第一講書人閱讀 60,237評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮楔敌,結(jié)果婚禮上啤挎,老公的妹妹穿的比我還像新娘。我一直安慰自己卵凑,他們只是感情好庆聘,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,237評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著勺卢,像睡著了一般伙判。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上黑忱,一...
    開封第一講書人閱讀 52,821評(píng)論 1 314
  • 那天宴抚,我揣著相機(jī)與錄音,去河邊找鬼甫煞。 笑死菇曲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抚吠。 我是一名探鬼主播常潮,決...
    沈念sama閱讀 41,236評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼楷力!你這毒婦竟也來(lái)了喊式?” 一聲冷哼從身側(cè)響起孵户,我...
    開封第一講書人閱讀 40,196評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎垃帅,沒(méi)想到半個(gè)月后延届,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體剪勿,經(jīng)...
    沈念sama閱讀 46,716評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贸诚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,794評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了厕吉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酱固。...
    茶點(diǎn)故事閱讀 40,928評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖头朱,靈堂內(nèi)的尸體忽然破棺而出运悲,到底是詐尸還是另有隱情,我是刑警寧澤项钮,帶...
    沈念sama閱讀 36,583評(píng)論 5 351
  • 正文 年R本政府宣布班眯,位于F島的核電站,受9級(jí)特大地震影響烁巫,放射性物質(zhì)發(fā)生泄漏署隘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,264評(píng)論 3 336
  • 文/蒙蒙 一亚隙、第九天 我趴在偏房一處隱蔽的房頂上張望磁餐。 院中可真熱鬧,春花似錦阿弃、人聲如沸诊霹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)脾还。三九已至,卻和暖如春入愧,著一層夾襖步出監(jiān)牢的瞬間荠呐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工砂客, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留泥张,地道東北人汹胃。 一個(gè)月前我還...
    沈念sama閱讀 49,378評(píng)論 3 379
  • 正文 我出身青樓喷楣,卻偏偏與公主長(zhǎng)得像夜赵,于是被迫代替她去往敵國(guó)和親眠副。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瞒瘸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,937評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容