Java四種引用類型

在Java中提供了四個(gè)級(jí)別的引用:強(qiáng)引用,軟引用,弱引用和虛引用犬性。

在這四個(gè)引用類型中,只有強(qiáng)引用FinalReference類是包內(nèi)可見(jiàn)腾仅,其他三種引用類型均為public乒裆,可以在應(yīng)用程序中直接使用。

引用類型的類結(jié)構(gòu)如圖所示推励。

1.強(qiáng)引用Java中的引用鹤耍,類似C語(yǔ)言中最難的指針。

通過(guò)引用验辞,可以對(duì)堆中的對(duì)象進(jìn)行操作稿黄。如:StringBuffer stringBuffer = new StringBuffer("Helloword");變量str指向StringBuffer實(shí)例所在的堆空間,通過(guò)str可以操作該對(duì)象受神。強(qiáng)引用的特點(diǎn):強(qiáng)引用可以直接訪問(wèn)目標(biāo)對(duì)象抛猖。強(qiáng)引用所指向的對(duì)象在任何時(shí)候都不會(huì)被系統(tǒng)回收。JVM寧愿拋出OOM異常鼻听,也不會(huì)回收強(qiáng)引用所指向的對(duì)象财著。強(qiáng)引用可能導(dǎo)致內(nèi)存泄漏。

2.軟引用:軟引用是除了強(qiáng)引用外撑碴,最強(qiáng)的引用類型撑教。

可以通過(guò)java.lang.ref.SoftReference使用軟引用。一個(gè)持有軟引用的對(duì)象醉拓,不會(huì)被JVM很快回收伟姐,JVM會(huì)根據(jù)當(dāng)前堆的使用情況來(lái)判斷何時(shí)回收。當(dāng)堆使用率臨近閾值時(shí)亿卤,才會(huì)去回收軟引用的對(duì)象愤兵。

因此,軟引用可以用于實(shí)現(xiàn)對(duì)內(nèi)存敏感的高速緩存排吴。SoftReference的特點(diǎn)是它的一個(gè)實(shí)例保存對(duì)一個(gè)Java對(duì)象的軟引用秆乳, 該軟引用的存在不妨礙垃圾收集線程對(duì)該Java對(duì)象的回收。也就是說(shuō),一旦SoftReference保存了對(duì)一個(gè)Java對(duì)象的軟引用后屹堰,在垃圾線程對(duì) 這個(gè)Java對(duì)象回收前肛冶,SoftReference類所提供的get()方法返回Java對(duì)象的強(qiáng)引用。一旦垃圾線程回收該Java對(duì)象之后扯键,get()方法將返回null睦袖。下面舉一個(gè)例子說(shuō)明軟引用的使用方法。在你的IDE設(shè)置參數(shù) -Xmx2m -Xms2m規(guī)定堆內(nèi)存大小為2m荣刑。

   @Test    public void test3(){ 
        MyObject obj = new myObject();
        SoftReference sf = new SoftReference<>(obj);obj = null; 
        System.gc();
        //        byte[] bytes = new byte[1024*100];
        //        System.gc();
        System.out.println("是否被回收"+sf.get());    }

運(yùn)行結(jié)果:是否被回收cn.zyzpp.MyObject@42110406打開(kāi)被注釋掉的new byte[1024*100]語(yǔ)句馅笙,這條語(yǔ)句請(qǐng)求一塊大的堆空間,使堆內(nèi)存使用緊張嘶摊。并顯式的再調(diào)用一次GC延蟹,結(jié)果如下:是否被回收null說(shuō)明在系統(tǒng)內(nèi)存緊張的情況下评矩,軟引用被回收叶堆。

3.弱引用:弱引用是一種比軟引用較弱的引用類型。

在系統(tǒng)GC時(shí)斥杜,只要發(fā)現(xiàn)弱引用虱颗,不管系統(tǒng)堆空間是否足夠,都會(huì)將對(duì)象進(jìn)行回收蔗喂。在java中忘渔,可以用java.lang.ref.WeakReference實(shí)例來(lái)保存對(duì)一個(gè)Java對(duì)象的弱引用。

public void test3(){        

       MyObject obj = new MyObject();WeakReference sf = new WeakReference(obj);
       obj = null;System.out.println("是否被回收"+sf.get());
       System.gc();
       System.out.println("是否被回收"+sf.get());    }

運(yùn)行結(jié)果:是否被回收cn.zyzpp.MyObject@42110406是否被回收null軟引用缰儿,弱引用都非常適合來(lái)保存那些可有可無(wú)的緩存數(shù)據(jù)畦粮,如果這么做,當(dāng)系統(tǒng)內(nèi)存不足時(shí)乖阵,這些緩存數(shù)據(jù)會(huì)被回收宣赔,不會(huì)導(dǎo)致內(nèi)存溢出。而當(dāng)內(nèi)存資源充足時(shí)瞪浸,這些緩存數(shù)據(jù)又可以存在相當(dāng)長(zhǎng)的時(shí)間儒将,從而起到加速系統(tǒng)的作用。

4.虛引用:虛引用是所有類型中最弱的一個(gè)对蒲。

一個(gè)持有虛引用的對(duì)象钩蚊,和沒(méi)有引用幾乎是一樣的,隨時(shí)可能被垃圾回收器回收蹈矮。當(dāng)試圖通過(guò)虛引用的get()方法取得強(qiáng)引用時(shí)砰逻,總是會(huì)失敗。并且泛鸟,虛引用必須和引用隊(duì)列一起使用蝠咆,它的作用在于跟蹤垃圾回收過(guò)程。當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí)谈况,如果發(fā)現(xiàn)它還有虛引用勺美,就會(huì)在垃圾回收后递胧,銷毀這個(gè)對(duì)象,將這個(gè)虛引用加入引用隊(duì)列赡茸。程序可以通過(guò)判斷引用隊(duì)列中是否已經(jīng)加入了虛引用缎脾,來(lái)了解被引用的對(duì)象是否將要被垃圾回收。如果程序發(fā)現(xiàn)某個(gè)虛引用已經(jīng)被加入到引用隊(duì)列占卧,那么就可以在所引用的對(duì)象的內(nèi)存被回收之前采取必要的行動(dòng)遗菠。

   public void test3(){ 
       MyObject obj = new MyObject();ReferenceQueue referenceQueue = new ReferenceQueue<>();
       PhantomReference sf = new PhantomReference<>(obj,referenceQueue); 
       obj = null;
       System.out.println("是否被回收"+sf.get());
       System.gc();
       System.out.println("是否被回收"+sf.get());
   }

運(yùn)行結(jié)果:是否被回收null是否被回收null對(duì)虛引用的get()操作,總是返回null华蜒,因?yàn)閟f.get()方法的實(shí)現(xiàn)如下: public T get() { return null; }

5.WeakHashMap類及其實(shí)現(xiàn)WeakHashMap類在java.util包內(nèi)辙纬,它實(shí)現(xiàn)了Map接口,是HashMap的一種實(shí)現(xiàn)叭喜,它使用弱引用作為內(nèi)部數(shù)據(jù)的存儲(chǔ)方案贺拣。

WeakHashMap是弱引用的一種典型應(yīng)用,它可以作為簡(jiǎn)單的緩存表解決方案捂蕴。一下兩段代碼分別使用WeakHashMap和HashMap保存大量的數(shù)據(jù):

public void test(){     
                               Map map;        
                               map = new WeakHashMap();    
                               for (int i =0;i<10000;i++){  
                               map.put("key"+i,new byte[i]);}
                               // map = new HashMap();
                               //    for (int i =0;i<10000;i++){
                                     //  map.put("key"+i,new byte[i]);
                               //}   
}

使用-Xmx2M限定堆內(nèi)存譬涡,使用WeakHashMap的代碼正常運(yùn)行結(jié)束,而使用HashMap的代碼段拋出異常java.lang.OutOfMemoryError: Java heap space

由此可見(jiàn)啥辨,WeakHashMap會(huì)在系統(tǒng)內(nèi)存緊張時(shí)使用弱引用涡匀,自動(dòng)釋放掉持有弱引用的內(nèi)存數(shù)據(jù)。但如果WeakHashMap的key都在系統(tǒng)內(nèi)持有強(qiáng)引用溉知,那么WeakHashMap就退化為普通的HashMap陨瘩,因?yàn)樗械谋眄?xiàng)都無(wú)法被自動(dòng)清理。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末级乍,一起剝皮案震驚了整個(gè)濱河市舌劳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卡者,老刑警劉巖蒿囤,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異崇决,居然都是意外死亡材诽,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門恒傻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)脸侥,“玉大人,你說(shuō)我怎么就攤上這事盈厘≌稣恚” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)外遇。 經(jīng)常有香客問(wèn)我注簿,道長(zhǎng),這世上最難降的妖魔是什么跳仿? 我笑而不...
    開(kāi)封第一講書人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任诡渴,我火速辦了婚禮,結(jié)果婚禮上菲语,老公的妹妹穿的比我還像新娘妄辩。我一直安慰自己,他們只是感情好山上,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布眼耀。 她就那樣靜靜地躺著,像睡著了一般佩憾。 火紅的嫁衣襯著肌膚如雪哮伟。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,245評(píng)論 1 299
  • 那天鸯屿,我揣著相機(jī)與錄音澈吨,去河邊找鬼把敢。 笑死寄摆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的修赞。 我是一名探鬼主播婶恼,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼柏副!你這毒婦竟也來(lái)了勾邦?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤割择,失蹤者是張志新(化名)和其女友劉穎眷篇,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體荔泳,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蕉饼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了玛歌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昧港。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖支子,靈堂內(nèi)的尸體忽然破棺而出创肥,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布叹侄,位于F島的核電站巩搏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏趾代。R本人自食惡果不足惜塔猾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望稽坤。 院中可真熱鬧丈甸,春花似錦、人聲如沸尿褪。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)杖玲。三九已至顿仇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間摆马,已是汗流浹背臼闻。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留囤采,地道東北人述呐。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蕉毯,于是被迫代替她去往敵國(guó)和親乓搬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

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