Java的四種引用型別
前言
Java的記憶體管理是通過虛擬機器來實現的,通過垃圾回收器釋放記憶體。而物件的引用型別也就影響著是否會被回收
強引用(StrongReference)
Java通常建立物件的引用方式,垃圾回收機制並不會回收該型別物件,即使出現OOM異常
void fun(){
Object o = new Object();
}
但在執行完fun()後,o這個物件會被回收。當中斷某個強引用物件與某個物件的關聯時,可以對強引用物件賦值為null,JVM會在適當時機回收該引用
軟引用(SoftReference)
軟引用需要用SoftReference類來實現,對於只有軟引用的物件來說,當系統記憶體足夠時它不會被回收,當系統記憶體空間不足時它會被回收。軟引用通常用在對記憶體敏感的程式中,也就是用於快取中,避免記憶體洩漏和溢位。
String str = new String("Hello");
SoftReference<String> sr = new SoftReference<String>(str);
當執行完這段程式碼,因為str是強引用物件。我們已經對str進行軟引用,現在就可以終止str對String的強引用。
str = null;
也可以重新獲取String物件,並用強引用指向它
str = sr.get();
所以正常通過是軟引用來輸出時
System.out.println(sr.get());
當JVM正常執行是,輸出Hello,當JVM對該軟引用物件回收後,輸出** null**
在JVM丟擲OOM異常前,垃圾回收執行緒會盡量回收長時間沒有使用的軟引用物件
弱引用(WeakReference)
當一個物件是被弱引用指向時,當JVM進行垃圾回收時,無論記憶體是否充足,會被回收。
String str=new String("hello");
WeakReference<String> wr = new WeakReference<String>(str);
str=null; //結束強引用
System.out.println(rf.get());
System.gc(); //開始垃圾回收
System.out.println(sf.get ());
第一次輸出Hello,當進行垃圾回收後,輸出null
虛引用(PhantomReference)
如果一個引用和虛引用關聯,則和沒有引用關聯一樣,jvm會將其回收。虛引用需要和引用佇列聯合使用,需要將虛引用加入引用佇列中,如果虛引用已加入引用佇列,那麼會被虛引用引用的物件將會被回收。它不能單獨使用,虛引用的主要作用是跟蹤物件被垃圾回收的狀態。
ReferenceQueue<String>queue=new ReferenceQueue<>();
String str=new String("hello world");
PhantomReference<String>ph=new PhantomReference<>(str,queue);
System.out.println(ph.get());
輸出null
注:
虛引用可以用來做一些精細的記憶體控制操作。
虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用佇列(ReferenceQueue)聯合使用。當垃 圾回收器準備回收一個物件時,如果發現它還有虛引用,就會在回收物件的記憶體之前,把這個虛引用加入到與之關聯的引用佇列中。程式可以通過判斷引用佇列中是 否已經加入了虛引用,來了解被引用的物件是否將要被垃圾回收。程式如果發現某個虛引用已經被加入到引用佇列,那麼就可以在所引用的物件的記憶體被回收之前採取必要的行動。