Glide弱引用緩存與java的強(qiáng)引用桃漾、軟引用、弱引用拟逮、幻象引用撬统,引用隊(duì)列總結(jié)

java的強(qiáng)引用、軟引用敦迄、弱引用恋追、幻象引用,引用隊(duì)列總結(jié)

  • java除了原始數(shù)據(jù)類型的變量罚屋,其他所有都是引用類型苦囱。
  • 引用分為強(qiáng)引用、軟引用脾猛、弱引用撕彤、幻象引用,這幾種引用影響著對象的回收

強(qiáng)引用

  • 強(qiáng)引用:形如Object object = new Object();這樣就是典型的強(qiáng)引用猛拴,被強(qiáng)引用引用的對象不會(huì)被垃圾收集器主動(dòng)回收羹铅,JVM寧愿拋出OutOfMemoryError運(yùn)行時(shí)錯(cuò)誤(OOM),使程序異常終止愉昆,也不會(huì)靠隨意回收具有強(qiáng)引用的“存活”對象來解決內(nèi)存不足的問題职员。對于一個(gè)普通的對象,如果沒有其他的引用關(guān)系跛溉,只要超過了引用的作用域或者顯式地將相應(yīng)強(qiáng)引用賦值為 null焊切,這個(gè)被引用的對象就是可以被垃圾回收器回收的(具體回收時(shí)機(jī)還是要看垃圾收集策略)扮授。

引用(Reference類)

  • 先在這里說一下,軟引用(SoftReference)蛛蒙、弱引用(WeakReference)糙箍、幻象引用(PhantomReference)都是java.lang.ref.Reference的子類,這個(gè)Reference類主要有4個(gè)方法
    • void clean();清除此參考對象牵祟。(此方法僅由Java代碼調(diào)用; 當(dāng)垃圾收集器清除引用時(shí)深夯,它直接執(zhí)行,而不調(diào)用此方法诺苹。)
    • boolean enqueue();將此引用對象添加到其注冊的隊(duì)列(如果有)咕晋。
    • T get();返回此引用對象的指示。(通過這個(gè)方法可以返回Reference所引用的對象收奔,可以重新變成強(qiáng)引用) 例如:軟引用引用的一個(gè)對象
MyObject aRef = new MyObject();
SoftReference aSoftRef=new SoftReference(aRef);
aRef = null;
//現(xiàn)在只有一個(gè)軟引用指向MyObject的這個(gè)對象掌呜,
//如果這個(gè)對象還沒有被回收,可以把他再次變?yōu)閺?qiáng)引用
if(aSoftRef.get() != null)
  MyObject bRef = aSoftRef.get();
//這個(gè)時(shí)候MyObject這個(gè)對象又變成強(qiáng)引用
復(fù)制代碼
  • boolean isEnqueued();通過程序或垃圾收集器來告知這個(gè)引用對象是否已經(jīng)入隊(duì);

  • 其中enqueue 和 isEnqueued 這兩個(gè)方法涉及到引用隊(duì)列坪哄,我們后面會(huì)講到质蕉。這里就先不解釋,留個(gè)印象就行翩肌。

軟引用(SoftReference)

  • 軟引用通過SoftReference類實(shí)現(xiàn)模暗。軟引用的生命周期比強(qiáng)引用短一些。只有當(dāng) JVM 認(rèn)為內(nèi)存不足時(shí)念祭,才會(huì)去試圖回收軟引用指向的對象:即JVM 會(huì)確保在拋出 OutOfMemoryError 之前兑宇,清理軟引用指向的對象。軟引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用粱坤,如果軟引用所引用的對象被垃圾回收器回收隶糕,Java虛擬機(jī)就會(huì)把這個(gè)軟引用(注意是引用本身這個(gè)對象(就是Reference自己,并不是引用所引用的對象)加入到與之關(guān)聯(lián)的引用隊(duì)列中站玄。后續(xù)枚驻,我們可以調(diào)用ReferenceQueue的poll()方法來檢查是否有它所關(guān)心的對象被回收(因?yàn)樵谶@個(gè)隊(duì)列里面的引用所指向的對象都被回收了)。如果隊(duì)列為空株旷,將返回一個(gè)null,否則該方法返回隊(duì)列中前面的一個(gè)Reference對象再登。

  • 應(yīng)用場景:軟引用通常用來實(shí)現(xiàn)內(nèi)存敏感的緩存。如果還有空閑內(nèi)存灾常,就可以暫時(shí)保留緩存霎冯,當(dāng)內(nèi)存不足時(shí)清理掉铃拇,這樣就保證了使用緩存的同時(shí)钞瀑,不會(huì)耗盡內(nèi)存。

弱引用(WeakReference)

  • 弱引用通過WeakReference類實(shí)現(xiàn)慷荔。 弱引用的生命周期比軟引用短雕什。在垃圾回收器線程掃描它所管轄的內(nèi)存區(qū)域的過程中,一旦發(fā)現(xiàn)了具有弱引用的對象,不管當(dāng)前內(nèi)存空間足夠與否贷岸,都會(huì)回收它的內(nèi)存壹士。由于垃圾回收器是一個(gè)優(yōu)先級很低的線程,因此不一定會(huì)很快回收弱引用的對象偿警。弱引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用躏救,如果弱引用所引用的對象被垃圾回收,Java虛擬機(jī)就會(huì)把這個(gè)弱引用加入到與之關(guān)聯(lián)的引用隊(duì)列中(和引用隊(duì)列一起使用同上面的軟引用)螟蒸。

  • 應(yīng)用場景:弱應(yīng)用同樣可用于內(nèi)存敏感的緩存盒使。

幻象引用(PhantomReference)

  • 幻象引用也叫虛引用,通過PhantomReference類來實(shí)現(xiàn)七嫌。無法通過虛引用訪問對象的任何屬性或函數(shù)少办。幻象引用僅僅是提供了一種確保對象被 finalize 以后诵原,做某些事情的機(jī)制英妓。如果一個(gè)對象僅持有虛引用,那么它就和沒有任何引用一樣绍赛,在任何時(shí)候都可能被垃圾回收器回收蔓纠。虛引用必須和引用隊(duì)列 (ReferenceQueue)聯(lián)合使用。當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對象時(shí)惹资,如果發(fā)現(xiàn)它還有虛引用贺纲,就會(huì)在回收對象的內(nèi)存之前,把這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中褪测。程序可以通過判斷引用隊(duì)列中是否已經(jīng)加入了虛引用猴誊,來了解被引用的對象是否將要被垃圾回收。如果程序發(fā)現(xiàn)某個(gè)虛引用已經(jīng)被加入到引用隊(duì)列侮措,那么就可以在所引用的對象的內(nèi)存被回收之前采取一些程序行動(dòng)(和引用隊(duì)列一起使用同上面軟引用跟弱引用)懈叹。

  • 應(yīng)用場景:可用來跟蹤對象被垃圾回收器回收的活動(dòng),當(dāng)一個(gè)虛引用關(guān)聯(lián)的對象被垃圾收集器回收之前會(huì)收到一條系統(tǒng)通知

引用隊(duì)列(ReferenceQueue):

  • Reference對象已經(jīng)不再具有存在的價(jià)值分扎,需要一個(gè)適當(dāng)?shù)那宄龣C(jī)制澄成,避免大量SoftReference對象帶來的內(nèi)存泄漏。在java.lang.ref包里還提供了ReferenceQueue畏吓。
  • 前面說到在使用軟引用墨状、虛引用、幻象引用的時(shí)候可以指定一個(gè)引用隊(duì)列菲饼,在引用所引用的對象被回收后引用本身就會(huì)進(jìn)入引用隊(duì)列肾砂。
    • 使用例子如下
ReferenceQueue queue = new ReferenceQueue();
SoftReference ref=new SoftReference(aMyObject,queue);
復(fù)制代碼
  • 通過引用隊(duì)列可以看到哪些Reference對象所引用的對象已經(jīng)被回收,當(dāng)調(diào)用引用隊(duì)列的poll()方法就可以返回除隊(duì)列中的失去所引用對象的Reference對象
  • 利用這個(gè)方法宏悦,我們可以檢查哪個(gè)SoftReference所軟引用的對象已經(jīng)被回收镐确。于是我們可以把這些失去所軟引用的對象的SoftReference對象清除掉包吝。
SoftReference ref = null;
while ((ref = (EmployeeRef) q.poll()) != null) {
// 清除ref
}
復(fù)制代碼

一些應(yīng)用

  • 軟引用和弱引用可以用來做一些內(nèi)存敏感的緩存,空間足夠的時(shí)候就緩存對象源葫,不夠的時(shí)候就回收诗越,不會(huì)拋出ome(內(nèi)存溢出異常,網(wǎng)上有很多這種小demo息堂,我這里就不贅述了)
  • entry的key是弱引用從他的構(gòu)造函數(shù)可以看出嚷狞,為什么是弱引用呢,因?yàn)楫?dāng)threadlocal對象不在使用的時(shí)候?qū)⑵渲梦籲ull荣堰,但是這個(gè)時(shí)候entry的key還是指向的threadlocal對象感耙,如果這個(gè)時(shí)候是強(qiáng)引用就會(huì)導(dǎo)致threadlocal對象沒辦法回收會(huì)造成內(nèi)存泄漏,所以改成弱引用的話當(dāng)只有一個(gè)弱引用的entry的key指向threadlocal對象的時(shí)候Threadlocal對象在垃圾回收的時(shí)候就會(huì)被回收掉持隧。(這里涉及一些ThreadLocal的底層實(shí)現(xiàn)即硼,大家可以看我這一篇博客(juejin.im/post/684490…

在強(qiáng)引用、軟引用屡拨、弱引用只酥、幻象引用的介紹我引用了一些其他博客下的評論衣洁,由于不好貼鏈接就只能聲明一下吧冠骄。

Glide中的弱引用及引用隊(duì)列使用

glide中弱引用gc回收之后,再回到內(nèi)存緩存:具體操作就是弱引用存入到引用隊(duì)列中之后凿蒜,再從引用隊(duì)列放入到內(nèi)存緩存哥艇,里面主要做了一個(gè)弱引用回收的監(jiān)聽绝编,一旦監(jiān)聽到了弱引用被回收,立馬就去引用隊(duì)列中將其取出到內(nèi)存緩存貌踏,然后再由從引用隊(duì)列中移除十饥。

Glide中為什么有弱引用緩存

因?yàn)長ru算法,他是最近最少使用原則的回收策略祖乳;所以可能導(dǎo)致正在使用的圖片被回收逗堵,如果用了弱引用的緩存,就可以保證它正在使用的時(shí)候不會(huì)被回收眷昆,這樣就實(shí)現(xiàn)了正在使用資源與緩存資源的隔離蜒秤;正在使用資源不收到Lru算法的回收影響。
而且弱引用對象亚斋,他的get()作媚,然后賦值給強(qiáng)引用對象的時(shí)候,他就是多了個(gè)強(qiáng)引用了帅刊,就不會(huì)被回收了纸泡;當(dāng)沒有g(shù)et的弱引用被回收了,就會(huì)進(jìn)入到引用隊(duì)列厚掷,對弱引用進(jìn)行回收監(jiān)聽弟灼,當(dāng)觸發(fā)了回收,就立馬從引用隊(duì)列中獲取到相應(yīng)的對象加入到內(nèi)存緩存中冒黑。

Glide當(dāng)中監(jiān)聽弱引用回收

U{ZH%JM7RBK4%P0GR9M3EGH.png
YH%)9`)7WRM@L_570}JXWDO.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末田绑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子抡爹,更是在濱河造成了極大的恐慌掩驱,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冬竟,死亡現(xiàn)場離奇詭異欧穴,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)泵殴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門涮帘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人笑诅,你說我怎么就攤上這事调缨。” “怎么了吆你?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵弦叶,是天一觀的道長。 經(jīng)常有香客問我妇多,道長伤哺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任者祖,我火速辦了婚禮立莉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘七问。我一直安慰自己桃序,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布烂瘫。 她就那樣靜靜地躺著媒熊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪坟比。 梳的紋絲不亂的頭發(fā)上芦鳍,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音葛账,去河邊找鬼柠衅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛籍琳,可吹牛的內(nèi)容都是我干的菲宴。 我是一名探鬼主播贷祈,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼喝峦!你這毒婦竟也來了势誊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤谣蠢,失蹤者是張志新(化名)和其女友劉穎粟耻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體眉踱,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挤忙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谈喳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片册烈。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖婿禽,靈堂內(nèi)的尸體忽然破棺而出茄厘,到底是詐尸還是另有隱情,我是刑警寧澤谈宛,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布次哈,位于F島的核電站,受9級特大地震影響吆录,放射性物質(zhì)發(fā)生泄漏窑滞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一恢筝、第九天 我趴在偏房一處隱蔽的房頂上張望哀卫。 院中可真熱鬧,春花似錦撬槽、人聲如沸此改。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽共啃。三九已至,卻和暖如春暂题,著一層夾襖步出監(jiān)牢的瞬間移剪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工薪者, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纵苛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像攻人,于是被迫代替她去往敵國和親取试。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

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