java Reference

image.png

java 引用類型: 強(qiáng),軟尤误,弱侠畔,虛,引用對(duì)象的能力依次減弱损晤。

強(qiáng)引用 (FinalReference)

String a = new String ("aaa");

這里 a 即是強(qiáng)引用软棺。我們都知道java對(duì)象是被分配在jvm堆上的,當(dāng)程序中不再有可達(dá)性的引用指向java對(duì)象時(shí)尤勋,該對(duì)象即可被gc回收喘落。而被強(qiáng)引用指向的對(duì)象永遠(yuǎn)不會(huì)被gc。在虛擬機(jī)的實(shí)現(xiàn)過(guò)程中最冰,實(shí)際采用了 FinalReference 類對(duì)其進(jìn)行引用瘦棋。而 Finalizer,除了作為一個(gè)實(shí)現(xiàn)類外暖哨,更是在虛擬機(jī)中實(shí)現(xiàn)一個(gè) FinalizerThread赌朋,以使虛擬機(jī)能夠在所有的強(qiáng)引用被解除后實(shí)現(xiàn)內(nèi)存清理。

static {
        ThreadGroup tg = Thread.currentThread().getThreadGroup();
        for (ThreadGroup tgn = tg;
             tgn != null;
             tg = tgn, tgn = tg.getParent());
        Thread finalizer = new FinalizerThread(tg);
        finalizer.setPriority(Thread.MAX_PRIORITY - 2);
        finalizer.setDaemon(true);
        finalizer.start();
    }

在 GC 的過(guò)程中篇裁,當(dāng)一個(gè)強(qiáng)引用被釋放沛慢,由系統(tǒng)垃圾收集器標(biāo)記后的對(duì)象,會(huì)被加入 Finalizer 對(duì)象中的 ReferenceQueue 中去达布,并調(diào)用 Finalizer.runFinalizer() 來(lái)執(zhí)行對(duì)象的 finalize 方法团甲。

private void runFinalizer(JavaLangAccess jla) {
        synchronized (this) {
            if (hasBeenFinalized()) return;
            remove();
        }
        try {
            Object finalizee = this.get();
            if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
                jla.invokeFinalize(finalizee);

                /* 注意,這里需要清空棧中包含該變量的的 slot, 從而來(lái)減少因?yàn)橐粋€(gè)保守的 GC 實(shí)現(xiàn)所造成的變量未被回收的假象 */
                finalizee = null;
            }
        } catch (Throwable x) { }
        super.clear();
    }

注意往枣,標(biāo)記處所調(diào)用的 invokeFinalizeMethod 為 native 方法伐庭,由于 finalize 方法在 Object 類中被聲明為 protected粉渠,這里必須采用 native 方法才能調(diào)用。隨后通過(guò)將本地強(qiáng)引用設(shè)置為空圾另,以便使垃圾回收器清理內(nèi)存霸株。

強(qiáng)引用有以下特征:

  • 可直接訪問(wèn)對(duì)象

  • 被強(qiáng)引用指向的對(duì)象即便在gc時(shí)也不會(huì)被回收,系統(tǒng)寧可發(fā)生OOM

  • 強(qiáng)引用可能導(dǎo)致內(nèi)存泄漏(這里補(bǔ)充一下內(nèi)存泄漏與內(nèi)存溢出的區(qū)別: 內(nèi)存泄漏是指本該被回收的對(duì)象沒(méi)有被回收集乔,內(nèi)存溢出是指內(nèi)存容量已達(dá)上限去件,再往里加就溢出了,就像是水桶滿了再加水就溢到外面了)

軟引用(SoftReference)

 SoftReference<Integer> softReference = new SoftReference<>(1);
 softReference.get(); // 1

軟引用指向?qū)ο蟮哪芰Υ斡趶?qiáng)引用扰路,當(dāng)內(nèi)存容量充足時(shí)并不會(huì)對(duì)軟引用所指向的對(duì)象有何影響尤溜,但是當(dāng)內(nèi)存容量不足時(shí),將會(huì)回收其指向的對(duì)象汗唱。首先會(huì)清空它的softReference宫莱,也就是softReference.get()返回null,然后再調(diào)用對(duì)象的finalize()方法哩罪,并在下一輪的gc中對(duì)其做真正的回收授霸。軟引用有以下特征:

  • 通過(guò)get()取得對(duì)象強(qiáng)引用來(lái)訪問(wèn)對(duì)象
  • 內(nèi)存吃緊情況下將會(huì)被回收

弱引用(WeakReference)

 WeakReference<Integer> weakReference = new WeakReference<>(1);
 weakReference.get(); // 1

弱引用指向?qū)ο蟮哪芰τ秩跤谲浺谩F涮匦钥绍浺没鞠嗨萍什澹煌氖?strong>不管內(nèi)存容量是否充足碘耳,只要發(fā)生了gc,都會(huì)對(duì)其進(jìn)行回收框弛。即get() 返回的都是null辛辨。 弱引用有以下特征:

  • 通過(guò)get()取得對(duì)象強(qiáng)引用來(lái)訪問(wèn)對(duì)象
  • 不管內(nèi)存是否吃緊,發(fā)生gc都會(huì)被回收

虛引用(PhantomReference)

ReferenceQueue queue = new ReferenceQueue();
PhantomReference phantomReference = new PhantomReference<>("aaa" ,queue);

虛引用是“最弱的” 引用類型瑟枫。它的構(gòu)造函數(shù)需要一個(gè)ReferenceQueue參數(shù)而且它不能通過(guò)get來(lái)獲取對(duì)象斗搞,因?yàn)樗膅et() 方法返回的永遠(yuǎn)是null。
public T get() { return null; }

那虛引用的作用是什么呢力奋? 其實(shí)虛引用主要是被用來(lái) 跟蹤對(duì)象被垃圾回收的狀態(tài)榜旦,通過(guò)查看引用隊(duì)列中是否包含對(duì)象的虛引用來(lái)判斷它是否即將被回收。目標(biāo)對(duì)象被gc回收前景殷,虛引用會(huì)被放入一個(gè)ReferenceQueue對(duì)象中,從而達(dá)到跟蹤對(duì)象被gc的作用澡屡。虛引用有以下特征:

  • 虛引用無(wú)法通過(guò)get()方法獲取對(duì)象
  • 虛引用所指向的對(duì)象在被gc前猿挚,會(huì)將虛引用放一個(gè)ReferenceQueue中從面跟蹤對(duì)象gc

值得注意的是,SoftReference, WeakReference 以及 PhantomReference 的構(gòu)造函數(shù)都可以接收一個(gè) ReferenceQueue 對(duì)象驶鹉。但是SoftReference, WeakReference在他們所指向的對(duì)象準(zhǔn)備被gc回收時(shí)绩蜻,調(diào)用對(duì)象finalize()方法之前,它們自身都會(huì)被放入這個(gè)queue中室埋。而PhantomReference只有當(dāng)gc對(duì)其所指向的對(duì)象真正進(jìn)行回收時(shí)办绝,才會(huì)放入這個(gè)queue中伊约。


總結(jié):

  • 強(qiáng)引用 (FinalReference), 這是最常用的引用類型 . JVM 系統(tǒng)采用 Finalizer 來(lái)管理每個(gè)強(qiáng)引用對(duì)象 , 并將其被標(biāo)記要清理時(shí)加入 ReferenceQueue, 并逐一調(diào)用該對(duì)象的 finalize() 方法 .

  • 軟引用 (SoftReference), 引用類型表現(xiàn)為當(dāng)內(nèi)存接近滿負(fù)荷 , 或?qū)ο笥?SoftReference.get() 方法的調(diào)用沒(méi)有發(fā)生一段時(shí)間后 , 垃圾回收器將會(huì)清理該對(duì)象 . 在運(yùn)行對(duì)象的 finalize 方法前 , 會(huì)將軟引用對(duì)象加入 ReferenceQueue 中去 .

  • 弱引用 (WeakReference), 引用類型表現(xiàn)為當(dāng)系統(tǒng)垃圾回收器開(kāi)始回收時(shí) , 則立即會(huì)回收該對(duì)象的引用 . 與軟引用一樣 , 弱引用也會(huì)在運(yùn)行對(duì)象的 finalize 方法之前將弱引用對(duì)象加入 ReferenceQueue.

  • 虛引用 (PhantomReference), 這是一個(gè)最虛幻的引用類型 . 無(wú)論是從哪里都無(wú)法再次返回被虛引用所引用的對(duì)象 . 虛引用在系統(tǒng)垃圾回收器開(kāi)始回收對(duì)象時(shí) , 將直接調(diào)用 finalize() 方法 , 但不會(huì)立即將其加入回收隊(duì)列 . 只有在真正對(duì)象被 GC 清除時(shí) , 才會(huì)將其加入 Reference 隊(duì)列中去 .

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市孕蝉,隨后出現(xiàn)的幾起案子屡律,更是在濱河造成了極大的恐慌,老刑警劉巖降淮,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件超埋,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡佳鳖,警方通過(guò)查閱死者的電腦和手機(jī)霍殴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)系吩,“玉大人来庭,你說(shuō)我怎么就攤上這事〈┌ぃ” “怎么了巾腕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)絮蒿。 經(jīng)常有香客問(wèn)我尊搬,道長(zhǎng),這世上最難降的妖魔是什么土涝? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任佛寿,我火速辦了婚禮,結(jié)果婚禮上但壮,老公的妹妹穿的比我還像新娘冀泻。我一直安慰自己,他們只是感情好蜡饵,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布弹渔。 她就那樣靜靜地躺著,像睡著了一般溯祸。 火紅的嫁衣襯著肌膚如雪肢专。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天焦辅,我揣著相機(jī)與錄音博杖,去河邊找鬼。 笑死筷登,一個(gè)胖子當(dāng)著我的面吹牛剃根,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播前方,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼狈醉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼廉油!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起苗傅,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤抒线,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后金吗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體十兢,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年摇庙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了旱物。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡卫袒,死狀恐怖宵呛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情夕凝,我是刑警寧澤宝穗,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站码秉,受9級(jí)特大地震影響逮矛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜转砖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一须鼎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧府蔗,春花似錦晋控、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至不铆,卻和暖如春蝌焚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狂男。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工综看, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人岖食。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像舞吭,于是被迫代替她去往敵國(guó)和親泡垃。 傳聞我的和親對(duì)象是個(gè)殘疾皇子析珊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

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