Java(九)Java中有四種引用你知道嗎?希望你不是最後一個知道的

一、爲什麼會有四種引用

01

在一開始當一個對象不被引用(就是沒有屬性/變量引用,例如Object ob=new Object();ob=null;)時,就會被JVM自動回收,在沒有等於null之前就是強引用

打個比方,就像你去餐廳喫飯,你站在位置上就是引用了這個位置,服務員(JVM)就不會過來收走你的餐具,當你走了,服務員就會收走你的餐具

02

隨着Java的發展,需求也越來越多樣化了,有些人希望當一個對象不被引用時也不要被收走,而是在內存保存一段時間,於是軟引用就誕生了。

接着上面的例子,餐廳的老闆(Java的開發者)覺得啊,這樣不行啊,客人一走開就把人家的餐具收走了,不僅讓客人喫的越來越少,還讓客人越來越不想來這裏喫東西了,於是就給了來用餐的客人一個牌子,上面寫着“有人用餐”,這樣服務員就不會在客人一走開,就把餐具給走了

03

還有人只是想在短期內使用一個對象,並不想去管理它什麼時候取消引用,讓JVM自動清理,於是弱引用就出現了,弱引用是和強引用相對的,強指的是對對象有絕對的控制權,而弱則是不想控制對象,全部交有JVM來處理。

接上例,餐廳的老闆又覺得,這樣也不太行啊,給了客人一個牌子,雖然可以讓客人避免了被收餐具,但是這樣卻給餐廳帶來了麻煩,有些客人故意放個牌子,又不知道什麼時候來用餐,於是又在牌子上加了一條規矩,如果在離開後十分鐘不在位置上,服務員就會將餐具收走

04

還有一些人,在用弱引用或軟引用的基礎上,想判斷這個對象是否被JVM清理掉了,於是虛引用就出來了,虛引用不是提供給JVM的,而是提供給開發人員的,方便開發人員查看對象是否被清理

接上例,老闆接到很多投訴,說我還要回來用餐的,但是餐具還是被收走了,老闆就想,的確有問題啊,得想個辦法。於是決定給每個位置陪一個通訊器,在服務員要收餐具時,就通過通訊器告訴客人

二、四種引用

上面也只是對四種引用進行了一個簡單的介紹,接下來會結合代碼分別對這四種引用做一個更加詳細的介紹

1

強引用

強引用,意味着,一個對象被某個屬性/字段引用着,JVM不會對這個對象進行回收,當內存空間不足時,JVM寧可拋出OutOfM moryError(內存溢出錯誤),也不會回收這個對象

強引用就是最普通的引用,一般是用在對象不可隨意被刪除的情況下

代碼public static void main(String[] args) throws Exception{System.out.println("start"); Object object=new Object(); System.gc();System.out.println(object); object=null; System.gc();System.out.println(object); System.out.println("end");}輸出startjava.lang.Object@14ae5a5nullend

2

軟引用

軟引用,就是對一個對象進行關聯,可以通過這個關聯找到對象,只有在內存不足時,JVM纔會回收該對象

軟引用需使用java.lang.ref.SoftReference類來實現,一般情況下是對有用但不是必要或者短期使用的對象使用,例如緩存,將數據存在內存中可以加快相應速度,當內存不夠時,刪除了緩存也不會有影響



代碼
public static void main(String[] args) throws Exception{
  System.out.println("start"); 
  Object object=new Object(); 
  System.gc();Thread.sleep(500);      
  SoftReference softReference=new SoftReference(object); 
  System.out.println(softReference.get()); 
  System.gc();Thread.sleep(500); 
  System.out.println(softReference.get());
  System.out.println("end"); 
 }
  結果
  start
  java.lang.Object@14ae5a5
  java.lang.Object@14ae5a5
  end

3

弱引用

弱引用也是對一個對象進行關聯,但是,當JVM進行定期gc或者內存不足時,就會將該對象回收,無論內存是否足夠

弱引用需要使用java.lang.ref.WeakReference類來實現,一般情況下,是對那些不重要的或者只當前使用一次的對象使用,例如,if中的判斷條件,如果只想進行一次判斷,就可以使用弱引用





代碼
public static void main(String[] args) throws Exception{
  System.out.println("start");
  Object object=new Object(); 
  System.gc();Thread.sleep(500); 
  WeakReference weakReference=new WeakReference(new Object()); 
  System.out.println(weakReference.get()); 
  System.gc();Thread.sleep(500); 
  System.out.println(weakReference.get());
  System.out.println("end");
 }
 結果
 start
 java.lang.Object@14ae5a5
 null
 end

4

虛引用

虛引用,則是一個虛構的引用,不會對對象的生存週期造成影響,只是一個檢測對象是否存在的工具

虛引用需要使用ReferenceQueue類和PhantomReference類來實現



代碼
public static void main(String[] args) throws Exception{
  System.out.println("start"); 
  Object object=new Object();
  ReferenceQueue q=new ReferenceQueue(); 
  PhantomReference<Object> phantomReference=new PhantomReference<Object>(object,q); 
  System.gc(); 
  Thread.sleep(500);
  //get()方法永遠返回null 
  System.out.println(phantomReference.isEnqueued());    
  object=null; System.gc(); 
  Thread.sleep(500);
  System.out.println(phantomReference.isEnqueued());
  System.out.println("end");
  }
  結果
  start
  false
  true
  end

最後

四種引用就講完啦,以後在編程的時候,可以考慮一下將後面這三種引用加入代碼中,可以提高對對象生存週期的控制

做一個總結吧

強引用,JVM不敢隨便清

弱引用,與強引用相對應

軟引用,對象什麼時候被回收都不能確定

虛引用,對象是否存在更確明

掃碼關注我

微信號 : cxy_xuxiaojian

在微信上也能看

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章