Java四種引用類型

java不同于c/c++,它不需要程序員自已來管理內存(分配,釋放內存),java 會自己來管理內存,比如銷毀某些不再被使用的對象。這些回收的操作都有jvm后臺的GC線程自己完成,但是在一些情況下,程序員因為開發環境和需求等因素,想介入這些回收的過程,至少是擁有一點點操控的權利,JDK給予了用戶這樣的操作入口,即四種引用類型。

強引用(Strong References)

強引用類型是我們平時寫代碼的時候最常用的引用,比如

Sample sample = new Sample();

new就是強引用,是在java堆中開辟一段內存空間,如果接下來

sample = null;

將引用指向一個空指針或者指向其他對象,那么剛才new出來的對象就沒有引用指向他,在GC進行可達性分析得時候就沒法找到鏈路能到達它,于是他會被回收掉。


軟引用(Soft References)

Sample sample = new Sample();  //首先用強引用sample指向該對象

/**使用java軟引用類SoftReference
 * 需要注意的是,softRef這個引用也是強引用,它是指向SoftReference這個對象的
 * 真正的軟引用被包裝在了softRef中
 */
SoftReference<Sample> softRef = new SoftReference<Sample>(sample);

//查看java.lang.Reference源碼發現
private T referent;     //這個才是軟引用, 只被jvm使用

軟引用在很多時候跟強引用一樣,沒有人指向該對象的時候,對象就會被回收,只不過,還有一種會被回收的情況就是,如果堆內存不足了,GC會把軟引用也回收,不管有沒有人指向他。

軟引用的構造方法還可以傳入ReferenceQueue,如下

private static final ReferenceQueue<Sample> QUEUE = new ReferenceQueue<>();
SoftReference<Sample> softRef = new SoftReference<Sample>(sample, QUEUE);

這個隊列的作用就是當jvm回收某個軟引用對象之后會將該SoftReference對象(例子中的softRef對象)添加進這個隊列,因此我們就知道這個對象啥時候被回收了,具體使用如下:

//while外面可以用定時器包裝
 while (true) {
       Reference<? extends Sample> poll = QUEUE.poll();
       if (poll != null) {
       //poll是softRef對象地址,不是referent地址
       System.out.println("--- 軟引用對象被jvm回收了 ---- " + poll);  
 }

打印結果


ReferenceQueue這個隊列除了強引用之外,其他三種引用都可以用。

弱引用(Weak Reference)

GC進行垃圾收集的時候,如果一個對象只有弱引用指向它,那么和沒有引用指向它是一樣的效果,GC都會回收他。也就是說,弱引用對象只能活到下一次GC。

WeakReference<Sample> weakRef = new WeakReference<Sample>(sample, QUEUE);

虛引用(Phantom Reference)

虛引用的構造方法必須強制傳入ReferenceQueue,因為在jvm回收前(重點: 對,就是回收前,軟引用和弱引用都是回收后),會將PhantomReference對象加入ReferenceQueue中;還有一點就是PhantomReference.get()方法永遠返回空,不管對象有沒有被回收,就是說無法通過虛引用來獲取對象實例。那么,其實虛引用對于一個對象來說不起任何作用,可有可無。

PhantomReference<Sample> phantomRef = new PhantomReference<>(sample, QUEUE);

那么為什么要引入虛引用,虛引用的唯一目的就是在一個對象實例被GC回收時,通過ReferenceQueue能獲得該對象被清理的消息通知。

本文整理自:http://blog.csdn.net/rodbate/article/details/72857447
感謝大佬?。?!

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容