Java的四種引用類型

Java中存在四種引用,分別為強(qiáng)引用(Strong Reference)身诺、軟引用(Soft Refefence)蜜托、弱引用(Weak Refefence)虛引用(Phantom Refefence),這四種引用的強(qiáng)度依次減弱霉赡。

一橄务、強(qiáng)引用

強(qiáng)引用就是指在程序代碼中普遍存在的,類似Object obj = new Object()這類的引用穴亏,只要強(qiáng)引用還存在蜂挪,垃圾收集器永遠(yuǎn)不會(huì)回收掉被引用的對(duì)象。如果沒有足夠的內(nèi)存嗓化,就會(huì)拋出內(nèi)存溢出異常棠涮。

public class StrongReferenceTest {

    private static final int MEGA_BYTE = 1024 * 1024;

    /**
     * -Xms10M -Xmx10M -Xmn5M
     */
    public static void main(String[] args) {
        byte[] tenMegaByte1 = new byte[MEGA_BYTE * 2];
        byte[] tenMegaByte2 = new byte[MEGA_BYTE * 2];
        byte[] tenMegaByte3 = new byte[MEGA_BYTE * 2];
        byte[] tenMegaByte4 = new byte[MEGA_BYTE * 2];
        byte[] tenMegaByte5 = new byte[MEGA_BYTE * 2];
    }
}

如上代碼所示,最大堆空間為10M刺覆,然后創(chuàng)建五個(gè)每個(gè)大小都為2M的大對(duì)象严肪,GC回收的時(shí)候發(fā)現(xiàn)這五個(gè)對(duì)象都是強(qiáng)引用,沒法回收內(nèi)存谦屑,拋出OutOfMemoryError驳糯。運(yùn)行結(jié)果如下:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at top.liaohuaida.reference.StrongReferenceTest.main(StrongReferenceTest.java:17)

二、軟引用

Java中提供了SoftReference類來實(shí)現(xiàn)軟引用氢橙。軟引用是用來描述一些還有用但并非必需的對(duì)象酝枢。對(duì)于軟引用的關(guān)聯(lián)著的對(duì)象,在系統(tǒng)將要發(fā)生內(nèi)存溢出異常之前悍手,將會(huì)把這些對(duì)象列進(jìn)回收范圍之中進(jìn)行第二次回收帘睦。如果這次回收還沒有足夠的內(nèi)存袍患,才會(huì)拋出內(nèi)存溢出異常。

public class SoftReferenceTest {

    private static final int MEGA_BYTE = 1024 * 1024;

    /**
     * -Xms10M -Xmx10M -Xmn5M
     */
    public static void main(String[] args) {
        SoftReference<byte[]> softReference1 = new SoftReference<byte[]>(new byte[MEGA_BYTE * 2]);
        System.gc();
        System.out.println("第一次GC后SoftReference的值:" + softReference1.get());
        SoftReference<byte[]> softReference2 = new SoftReference<byte[]>(new byte[MEGA_BYTE * 2]);
        System.gc();
        System.out.println("第二次GC后SoftReference的值:" + softReference1.get());
        SoftReference<byte[]> softReference3 = new SoftReference<byte[]>(new byte[MEGA_BYTE * 2]);
        System.gc();
        System.out.println("第三次GC后SoftReference的值:" + softReference1.get());
        SoftReference<byte[]> softReference4 = new SoftReference<byte[]>(new byte[MEGA_BYTE * 2]);
        System.gc();
        System.out.println("第四次GC后SoftReference的值:" + softReference1.get());
        System.gc();
        SoftReference<byte[]> softReference5 = new SoftReference<byte[]>(new byte[MEGA_BYTE * 2]);
        System.out.println("第五次GC后SoftReference的值:" + softReference1.get());
    }
}

如上代碼所示官脓,每次創(chuàng)建一個(gè)2M的對(duì)象之后协怒,就顯示調(diào)用一次System.gc()來回收內(nèi)存,結(jié)果如下所示卑笨,前四次回收并沒有回收掉softReference1關(guān)聯(lián)對(duì)象的內(nèi)存孕暇。但是第五次回收的時(shí)候,內(nèi)存不足赤兴,將要發(fā)生內(nèi)存溢出妖滔,此時(shí)softReference1關(guān)聯(lián)對(duì)象的內(nèi)存被回收,其實(shí)其他SoftReference關(guān)聯(lián)對(duì)象的內(nèi)存也都被回收掉了桶良。

第一次GC后SoftReference的值:[B@6d13722b
第二次GC后SoftReference的值:[B@6d13722b
第三次GC后SoftReference的值:[B@6d13722b
第四次GC后SoftReference的值:[B@6d13722b
第五次GC后SoftReference的值:null

三座舍、弱引用

Java提供了WeakReference類來實(shí)現(xiàn)弱引用。弱引用也是用來描述非必要對(duì)象的陨帆,但是它的強(qiáng)度比軟引用更弱一些曲秉,被弱引用關(guān)聯(lián)的對(duì)象只能生存到下一次垃圾收集發(fā)生之前。當(dāng)垃圾收集器工作時(shí)疲牵,無論當(dāng)前內(nèi)存是否足夠承二,都會(huì)回收掉只被弱引用關(guān)聯(lián)的對(duì)象。

public class WeakReferenceTest {
    private static final int MEGA_BYTE = 1024 * 1024;

    /**
     * -Xms10M -Xmx10M -Xmn5M
     */
    public static void main(String[] args) {
        WeakReference<byte[]> weakReference1 = new WeakReference<byte[]>(new byte[MEGA_BYTE * 2]);
        System.out.println("第一次GC前weakReference1的值:" + weakReference1.get());
        System.gc();
        System.out.println("第一次GC后weakReference1的值:" + weakReference1.get());
        WeakReference<byte[]> weakReference2 = new WeakReference<byte[]>(new byte[MEGA_BYTE * 2]);
        System.out.println("第二次GC前weakReference2的值:" + weakReference2.get());
        System.gc();
        System.out.println("第二次GC后weakReference2的值:" + weakReference2.get());
//        WeakReference<byte[]> weakReference3 = new WeakReference<byte[]>(new byte[MEGA_BYTE * 2]);
//        System.gc();
//        System.out.println("第三次GC后weakReference3的值:" + weakReference3.get());
//        WeakReference<byte[]> weakReference4 = new WeakReference<byte[]>(new byte[MEGA_BYTE * 2]);
//        System.gc();
//        System.out.println("第四次GC后weakReference4的值:" + weakReference4.get());
//        System.gc();
//        WeakReference<byte[]> weakReference5 = new WeakReference<byte[]>(new byte[MEGA_BYTE * 2]);
//        System.out.println("第五次GC后weakReference5的值:" + weakReference5.get());
    }
}

如上代碼所示纲爸,每次創(chuàng)建一個(gè)2M的對(duì)象之后亥鸠,就顯示調(diào)用一次System.gc()來回收內(nèi)存,結(jié)果如下所示识啦,每次回收內(nèi)存都會(huì)回收掉WeakReference關(guān)聯(lián)對(duì)象的內(nèi)存负蚊,而不管內(nèi)存是否充足。注釋掉的部分結(jié)果也是相同的颓哮。

第一次GC前weakReference1的值:[B@21a437b6
第一次GC后weakReference1的值:null
第二次GC前weakReference2的值:[B@8939ec3
第二次GC后weakReference2的值:null

四家妆、虛引用

Java提供PhantomReference類來實(shí)現(xiàn)虛引用。虛引用也被稱為幽靈引用或者幻影引用冕茅,它是一種最弱的引用關(guān)系揩徊。一個(gè)對(duì)象是否有虛引用的存在,完全不會(huì)對(duì)其生存時(shí)間構(gòu)成影響嵌赠,也無法通過虛引用來取得一個(gè)對(duì)象實(shí)例塑荒。在一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是能在這個(gè)對(duì)象被垃圾收集回收時(shí)收到一個(gè)系統(tǒng)通知。

五姜挺、參考

深入理解Java虛擬機(jī)

Java中的四種引用類型

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末齿税,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子炊豪,更是在濱河造成了極大的恐慌凌箕,老刑警劉巖拧篮,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異牵舱,居然都是意外死亡串绩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門芜壁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來礁凡,“玉大人,你說我怎么就攤上這事慧妄∏昱疲” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵塞淹,是天一觀的道長窟蓝。 經(jīng)常有香客問我,道長饱普,這世上最難降的妖魔是什么运挫? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮套耕,結(jié)果婚禮上滑臊,老公的妹妹穿的比我還像新娘。我一直安慰自己箍铲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布鬓椭。 她就那樣靜靜地躺著颠猴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪小染。 梳的紋絲不亂的頭發(fā)上翘瓮,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音裤翩,去河邊找鬼资盅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛踊赠,可吹牛的內(nèi)容都是我干的呵扛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼筐带,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼今穿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起伦籍,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蓝晒,失蹤者是張志新(化名)和其女友劉穎腮出,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芝薇,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胚嘲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了洛二。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馋劈。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖灭红,靈堂內(nèi)的尸體忽然破棺而出侣滩,到底是詐尸還是另有隱情,我是刑警寧澤变擒,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布君珠,位于F島的核電站,受9級(jí)特大地震影響娇斑,放射性物質(zhì)發(fā)生泄漏策添。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一毫缆、第九天 我趴在偏房一處隱蔽的房頂上張望唯竹。 院中可真熱鬧,春花似錦苦丁、人聲如沸浸颓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽产上。三九已至,卻和暖如春蛾狗,著一層夾襖步出監(jiān)牢的瞬間晋涣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國打工沉桌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谢鹊,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓留凭,卻偏偏與公主長得像佃扼,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蔼夜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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

  • 在Java中提供了四個(gè)級(jí)別的引用:強(qiáng)引用松嘶,軟引用,弱引用和虛引用挎扰。在這四個(gè)引用類型中翠订,只有強(qiáng)引用FinalRefe...
    墨雨軒夏閱讀 395評(píng)論 0 1
  • Java垃圾回收機(jī)制可以用 3 個(gè)詞來概括: where巢音, when 和 how? When: 對(duì)象何時(shí)需要被回收...
    六尺帳篷閱讀 2,063評(píng)論 0 7
  • 從JDK1.2版本開始尽超,把對(duì)象的引用分為四種級(jí)別官撼,從而使程序能更加靈活的控制對(duì)象的生命周期。這四種級(jí)別由 高到低依...
    Speronie閱讀 272評(píng)論 0 0
  • 引入 從JDK1.2前似谁,Java的引用只有可達(dá)和不可達(dá)的兩種傲绣。為了更好的控制對(duì)象的聲明周期,JDK1.2將引用分為...
    雁宇閱讀 1,089評(píng)論 0 4
  • 找尋曾經(jīng)拼命的自己 【今日三只】 生活學(xué)習(xí):心理fm&樊登讀書&筆記&作業(yè)&葉老師進(jìn)階課&和孩子認(rèn)識(shí)三個(gè)字巩踏,深度陪...
    張張happy閱讀 161評(píng)論 0 0