Android中深入學習對象的四種引用類型
前言:
Java中,一切被視為對象,引用則是用來操縱對象的;在JDK1.2就把對象引用分為四種級別,從而使程序能更靈活控制它的生命周期,級別由高到底依次為:強 > 軟 > 弱 > 虛引用;而GC
垃圾回收器(Garbage Collection
)對不同的類型有著不同的處理方法,瞭解這些處理方式有助於我們寫出更高質量的代碼。今天我們就來學習下
一、引用詳解
1、強引用 StrongReference
強引用是使用最普遍的引用。如果一個對象具有強引用,那垃圾回收器絕不會回收它。當內存空間不足,Java
虛擬機寧願拋出 OutOfMemoryError
錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足的問題。如代碼 String s=”abc”
中變量 s 就是字符串對象”abc
” 的一個強引用。隻要你給強引用對象 s
賦空值 null
, 該對象就可以被垃圾回收器回收;因為該對象此時不再含有其他強引用;
//str表示強引用,指向new String()這個對象 String str = new String();
2、弱引用
弱引用(WeakReference
)是弱於軟引用的引用類型,與軟引用類似,不同的是弱引用不能阻止垃圾回收,在垃圾回收機制運行時,如果一個對象的引用是弱引用的話,不管內存空間是否足夠,對象都會被回收。弱引用常常被用於防止內存泄漏,最常見的是單例和Handler
造成的內存泄漏;
//弱引用實例 WeakReference weakReference = new WeakReference<>(context); //獲取弱引用保存的引用 Context ctx = weakReference.get();
3、軟引用
SoftReference:
軟引用–>當虛擬機內存不足時,將會回收它指向的對象;需要獲取對象時,可以調用get
方法;
軟引用對象不會很快被jvm
回收,jvm
會根據當前堆的使用情況來判斷何時回收,當堆的使用頻率接近閥值時才會被回收;
基本用法:
MySoftReference msf = new MySoftReference(); SoftReference sf = new SoftReference(msf); MySoftReference mySoftReference =(MySoftReference) sf.get();
基本特點:
- 如果內存足夠,軟引用是不會被jvm回收的;
- 如果內存不夠,會根據堆棧的使用情況來回收引用;
- 未被回收的軟引用是一直可被程序占有的;
- 軟引用可以和引用隊列(ReferenceQueue)聯合使用來實現內存緊張的高速緩存;
- 如果軟引用引用的對象被回收,Java虛擬機會把改軟引用對象加到與之關聯的引用隊列中;
ReferenceQueue rq = new ReferenceQueue(); SoftReference sf = new SoftReference(msf,rf);
當軟引用對象被回收後,ReferenceQueue
隊列中存儲著強引用的Reference
,然後可通過poll()
來判斷當前引用隊列是否有失去軟引用的對象,如果隊列為空,將返回一個null
,否則該方法返回隊列中前面的一個Reference
對象。可以檢測出哪個軟引用對象被回收,然後將其清除;
Reference reference =null; while((reference==(EmployeeRef)rq.poll())){ //清除操作 reference =null; System.gc(); }
4、虛引用
虛引用(PhantomReference
)是最弱的引用,一個持有虛引用的對象和沒有引用幾乎是一樣的,隨時都可能被垃圾回收器回收。通過虛引用的get()方法獲取到的引用都會失敗(為null
),虛引用必須和引用隊列ReferenceQueue
一起使用;
ReferenceQueue
引用隊列作用在於跟蹤垃圾回收過程。當垃圾回收器回收對象時,如果發現它還有虛引用,就會在回收後銷毀這個對象,並且將虛引用指向的對象加入到引用隊列。隻能通過虛引用是否被加入到ReferenceQueue
來判斷虛引用是否為GC回收,這也是判斷對象是否為回收的唯一途徑;
Java的Object類中有finalize()方法,原理:一旦垃圾回收器準備釋放對象占用的內存空間,將首先調用finalize()
方法,並且在下一次垃圾回收動作發生時,才會真正回收對象占用的內存,但是問題在於,虛擬機不能保證finalize()
何時被調用,因為GC
運行時間不是固定的;
使用虛引用就能解決這個問題,虛引用主要用於跟蹤垃圾被回收的活動,主要用來實現比較精細的內存使用控制,這對Android
來說很有意義;
//引用隊列 ReferenceQueue queue = new ReferenceQueue<>(); //虛引用 PhantomReference phantomReference = new PhantomReference(new Object(), queue); Log.e(TAG, "虛引用:PhantomReference == " + phantomReference.get()); //系統垃圾回收 System.gc(); System.runFinalization();
phantomReference.get()
獲取的引用一直為null,調用系統回收垃圾,queue.poll()
獲取保存的引用對象,並且把它在這個隊列中移除;
虛引用無法通過get()方
法獲取目標的引用,一直都是返回null
,源碼:
public T get() { return null; }
總結:
- 強引用(
StrongReference
):不會自動回收,最難被GC
回收的,寧可拋出異常也不回收強引用指向的對象;任何場景; - 軟引用(
SoftReference
):內存不足時,GC
會回收軟引用指向的對象比較少使用,已被LruCache
替代; - 弱引用(
WeakReference
):不管內存足不足,隻要GC瞭都能回收弱引用指向的對象;常用於避免內存泄漏; - 虛引用(
PhantomReference
):隨時都能回收,也稱幽靈引用,相當於沒有指向任何實例引用;跟蹤對象是否被回收,很少使用;
到此這篇關於Android
中深入學習對象的四種引用類型的文章就介紹到這瞭,更多相關Android
中深入學習對象引用類型內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Java的四種引用方式
- 淺談JVM垃圾回收之哪些對象可以被回收
- Java面試題沖刺第二十九天–JVM3
- 四種引用類型在JAVA Springboot中的使用詳解
- java編程Reference核心原理示例源碼分析