1. 程式人生 > >Java的四種引用型別

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)聯合使用。當垃 圾回收器準備回收一個物件時,如果發現它還有虛引用,就會在回收物件的記憶體之前,把這個虛引用加入到與之關聯的引用佇列中。程式可以通過判斷引用佇列中是 否已經加入了虛引用,來了解被引用的物件是否將要被垃圾回收。程式如果發現某個虛引用已經被加入到引用佇列,那麼就可以在所引用的物件的記憶體被回收之前採取必要的行動。

參考資料