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