摘要:簡(jiǎn)單來(lái)說(shuō)就是引用和引用隊(duì)列關(guān)聯(lián)起來(lái)引用的構(gòu)造函數(shù)傳入隊(duì)列,然后引用被回收的時(shí)候會(huì)被添加到隊(duì)列中,然后使用方法可以返回引用。
引語(yǔ):
????我們知道java相比C,C++中沒(méi)有令人頭痛的指針,但是卻有和指針作用相似的引用對(duì)象(Reference),就是常說(shuō)的引用,比如,Object obj = new Object();這個(gè)obj就是引用,它指向的是真正的對(duì)象Object的地址,不過(guò)今天要說(shuō)的是java中的四種引用。有人可能比較懵逼,四種引用?是的,從JDK1.2之后,java對(duì)引用這塊的概念進(jìn)行了擴(kuò)充,按照引用的強(qiáng)度分為了四種引用:強(qiáng)引用,軟引用,弱引用,虛引用。下面就讓我們來(lái)看看這四種引用都具體的情況吧。
1.強(qiáng)引用 1.1介紹:我們平時(shí)代碼中使用得最多的引用,對(duì)象的類(lèi)是:StrongReference。就比如上面說(shuō)的Object obj = new Object();我們?cè)偈煜げ贿^(guò)了,作為最強(qiáng)的引用,只要引用還存在著,垃圾收集器就不會(huì)將該引用給回收,即使會(huì)出現(xiàn)OOM(內(nèi)存溢出)。就是說(shuō)這種引用只要引用還一直指向的對(duì)象,垃圾收集器是不會(huì)去管它的,所以它被稱(chēng)為強(qiáng)引用。不過(guò)如果
Object obj = new Object(); obj = null;
obj被賦值為了null,該引用就斷了,垃圾收集器會(huì)在合適的時(shí)候回收改引用的內(nèi)存。
還有一種情況就是obj是成員變量,方法執(zhí)行完了,obj隨著被棧幀被回收了,obj引用也是一起被回收了。強(qiáng)引用的使用就不介紹了,地球人都知道。
軟引用是用來(lái)描述一些有用但是非必須的對(duì)象。對(duì)應(yīng)的類(lèi)是SoftReference,它被回收的時(shí)機(jī)是系統(tǒng)內(nèi)存不足的時(shí)候,如果內(nèi)存足夠,它不會(huì)被回收,內(nèi)存不足了,可能會(huì)發(fā)生OOM了,軟引用的對(duì)象就會(huì)被回收。這樣的特性是不是就像緩存?是的,軟引用可以用來(lái)存放緩存的數(shù)據(jù),內(nèi)存足夠的時(shí)候一直可以訪(fǎng)問(wèn),內(nèi)存不足的時(shí)候,需要重新創(chuàng)建或者訪(fǎng)問(wèn)原對(duì)象。
2.2使用:其實(shí)不管是軟引用,弱引用,還是虛引用,代碼中使用方式都是像下面這樣,使用對(duì)應(yīng)的Reference將對(duì)象放入到構(gòu)造函數(shù)當(dāng)中,然后使用的地方reference.get()來(lái)調(diào)用具體對(duì)象。
Object obj = new Object(); SoftReference
同時(shí)可以使用ReferenceQueue來(lái)把引用和引用隊(duì)列給關(guān)聯(lián)起來(lái):
Object obj = new Object(); ReferenceQueue
所謂關(guān)聯(lián)起來(lái),其實(shí)就是當(dāng)引用被回收的時(shí)候,會(huì)被添加到ReferenceQueue中,使用ReferenceQueue.poll()方法可以返回當(dāng)前可用的引用,并從隊(duì)列沖刪除。簡(jiǎn)單來(lái)說(shuō)就是引用和引用隊(duì)列關(guān)聯(lián)起來(lái)(引用的構(gòu)造函數(shù)傳入隊(duì)列),然后引用被回收的時(shí)候會(huì)被添加到隊(duì)列中,然后使用poll()方法可以返回引用。
3.弱引用 3.1介紹:虛引用比上面兩個(gè)引用就更菜了,只要垃圾收集器掃描到了它,被弱引用關(guān)聯(lián)的對(duì)象就會(huì)被回收。被弱引用關(guān)聯(lián)對(duì)象的生命周期其實(shí)就是從對(duì)象創(chuàng)建到下一次垃圾回收。對(duì)應(yīng)的類(lèi)是WeakReference。
3.2使用:public static void main(String[] args) throws InterruptedException { Object obj = new Object(); ReferenceQueuerefQueue = new ReferenceQueue<>(); WeakReference weakRef = new WeakReference<>(obj, refQueue); System.out.println("引用:" + weakRef.get()); System.out.println("隊(duì)列中的東西:" + refQueue.poll()); // 清除強(qiáng)引用, 觸發(fā)GC obj = null; System.gc(); Thread.sleep(200); System.out.println("引用:" + weakRef.get()); System.out.println("引用加入隊(duì)列了嗎? " + weakRef.isEnqueued()); System.out.println("隊(duì)列中的東西:" + refQueue.poll()); /** * 輸出結(jié)果 * 引用:java.lang.Object@7bb11784 * 隊(duì)列中的東西:null * 引用:null * 引用加入隊(duì)列了嗎? true * 隊(duì)列中的東西:java.lang.ref.WeakReference@33a10788 */ }
可以看到當(dāng)強(qiáng)引用被清除,手動(dòng)觸發(fā)GC后,弱引用回收,被加入到隊(duì)列中了。
3.3擴(kuò)展:WeakHashMap跟hashMap很像,差別就在于,當(dāng)WeakHashMap的key(弱引用),指向的對(duì)象被回收了,weakhashMap中的對(duì)象也就消失了。不會(huì)和HashMap一樣一直持有該對(duì)象,導(dǎo)致無(wú)法回收。
不贅述了,有興趣的可以了解一下,WeakHashMap。
虛引用是最弱的一種引用,它不會(huì)影響對(duì)象的生命周期,對(duì)象被回收跟它沒(méi)啥關(guān)系。它引用的對(duì)象可以在任何時(shí)候被回收,而且也無(wú)法根據(jù)虛引用來(lái)取得一個(gè)對(duì)象的實(shí)例。僅僅當(dāng)它指向的對(duì)象被回收的時(shí)候,它會(huì)受到一個(gè)通知。對(duì)應(yīng)的類(lèi)是PhantomReference。
4.2使用:有人就要問(wèn)既然對(duì)對(duì)象回收沒(méi)影響,那它有啥用(其實(shí)用處很少),我查閱網(wǎng)上的資料說(shuō)是,可以用來(lái)監(jiān)控對(duì)象的回收,和記錄日志。簡(jiǎn)單點(diǎn)說(shuō)就是對(duì)象被回收的時(shí)候,和虛引用相關(guān)的隊(duì)列知道了實(shí)例對(duì)象被回收了。這個(gè)時(shí)候我們可以記錄下來(lái),知道對(duì)象是什么時(shí)候被回收的。
從而起到監(jiān)控的作用。
public static void main(String[] args) throws Exception { Object abc = new Object(); ReferenceQueuerefQueue = new ReferenceQueue (); PhantomReference abcRef = new PhantomReference (abc, refQueue); System.out.println("隊(duì)列中的東西:" + refQueue.poll()); abc = null; System.gc(); Thread.sleep(1000); System.out.println("引用加入隊(duì)列了嗎? " + abcRef.isEnqueued()); System.out.println("隊(duì)列中的東西:" + refQueue.poll()); /** * 輸出: * 隊(duì)列中的東西:null * 引用加入隊(duì)列了嗎? true * 隊(duì)列中的東西:java.lang.ref.PhantomReference@7bb11784 */ }
發(fā)現(xiàn)隊(duì)列中有引用了,就可以添加日志記錄了。
5.總結(jié):將人比作垃圾收集器,引用比作食物,我們來(lái)總結(jié)下四種引用:
強(qiáng)引用是毒藥,即使你很餓了你也不會(huì)去吃它;
軟引用是零食,不餓的時(shí)候不吃,餓了饑不擇食,零食也能填飽肚子;
弱引用是飯菜,到了吃飯時(shí)間(垃圾回收),就吃飯菜;
虛引用是剩菜,當(dāng)你吃完?yáng)|西(回收完對(duì)象),就回剩下剩菜,別人就知道你吃過(guò)飯了。
引用 | 回收時(shí)機(jī) | 使用場(chǎng)景 |
---|---|---|
強(qiáng) | 不會(huì)被回收 | 正常編碼使用 |
軟 | 內(nèi)存不夠了,被GC | 可作為緩存 |
弱 | GC發(fā)生時(shí) | 可作為緩存(WeakHashMap) |
虛 | 任何時(shí)候 | 監(jiān)控對(duì)象回收,記錄日志 |
1.https://blog.csdn.net/l540675...
2.https://www.iteye.com/topic/5...
3.https://www.geeksforgeeks.org...
4.https://blog.csdn.net/aitangy...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/74641.html
摘要:四種引用類(lèi)型在中,類(lèi)型就分為兩種,基本類(lèi)型和引用類(lèi)型或自定義類(lèi)型。軟引用可用來(lái)實(shí)現(xiàn)內(nèi)存敏感的高速緩存。一般用法是程序可以通過(guò)判斷引用隊(duì)列中是否已經(jīng)加入了虛引用,來(lái)了解被引用的對(duì)象是否將要被垃圾回收。 Java四種引用類(lèi)型 在java中,類(lèi)型就分為兩種,基本類(lèi)型和引用類(lèi)型或自定義類(lèi)型。 引用類(lèi)型又分為四種: 強(qiáng)引用 StrongReference 軟引用 SoftReference 若...
摘要:在之后,對(duì)引用的概念進(jìn)行了擴(kuò)充,將引用分為強(qiáng)引用軟引用弱引用虛引用種,這種引用強(qiáng)度依次逐漸減弱。軟引用是用來(lái)描述一些還有用但并非必需的對(duì)象。虛引用也稱(chēng)為幽靈引用或者幻影引用,它是最弱的一種引用關(guān)系。 以下內(nèi)容摘自《深入理解Java虛擬機(jī) JVM高級(jí)特性與最佳實(shí)踐》第2版,強(qiáng)烈推薦沒(méi)有看過(guò)的同學(xué)閱讀,讀完的感覺(jué)就是原來(lái)學(xué)的都是些什么瘠薄東西(╯‵□′)╯︵┴─┴ 在JDK1.2以前,Ja...
閱讀 3061·2021-11-25 09:43
閱讀 1037·2021-11-24 10:22
閱讀 1367·2021-09-22 15:26
閱讀 694·2019-08-30 15:44
閱讀 2471·2019-08-29 16:33
閱讀 3709·2019-08-26 18:42
閱讀 921·2019-08-23 18:07
閱讀 1841·2019-08-23 17:55