四種引用
強引用
強引用就是指在程式程式碼之中普遍存在的,比如下面這段程式碼中的object和str都是強引用:
Object object = new Object();
String str = "hello";
只要某個物件有強引用與之關聯,JVM必定不會回收這個物件,即使在記憶體不足的情況下,JVM寧願丟擲OutOfMemory錯誤也不會回收這種物件。
軟引用
軟引用是用來描述一些有用但並不是必需的物件,在Java中用java.lang.ref.SoftReference類來表示。對於軟引用關聯著的物件,只有在記憶體不足的時候JVM才會回收該物件。因此,這一點可以很好地用來解決OOM的問題,並且這個特性很適合用來實現快取:比如網頁快取、圖片快取
等。
SoftReference<String> sr = new SoftReference<String>(new String("hello"));
System.out.println(sr.get());
弱引用(WeakReference)
弱引用也是用來描述非必需物件的,當JVM進行垃圾回收時,無論記憶體是否充足,都會回收被弱引用關聯的物件。在java中,用java.lang.ref.WeakReference類來表示。
WeakReference<String> sr = new WeakReference<String>(new String("hello")); System.out.println(sr.get()); System.gc(); //通知JVM的gc進行垃圾回收 System.out.println(sr.get()); 輸出結果為: hello null
第二個輸出結果是null,這說明只要JVM進行垃圾回收,被弱引用關聯的物件必定會被回收掉。不過要注意的是,這裡所說的被弱引用關聯的物件是指只有弱引用與之關聯,如果存在強引用同時與之關聯,則進行垃圾回收時也不會回收該物件(軟引用也是如此)。
虛引用(PhantomReference)
虛引用和前面的軟引用、弱引用不同,它並不影響物件的生命週期。在java中用java.lang.ref.PhantomReference類表示。如果一個物件與虛引用關聯,則跟沒有引用與之關聯一樣,在任何時候都可能被垃圾回收器回收
要注意的是,虛引用必須和引用佇列關聯使用,當垃圾回收器準備回收一個物件時,如果發現它還有虛引用,就會把這個虛引用加入到與之 關聯的引用佇列中。程式可以通過判斷引用佇列中是否已經加入了虛引用,來了解被引用的物件是否將要被垃圾回收。如果程式發現某個虛引用已經被加入到引用佇列,那麼就可以在所引用的物件的記憶體被回收之前採取必要的行動。
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
System.out.println(pr.get());
舉例
假如有一個應用需要讀取大量的本地圖片,如果每次讀取圖片都從硬碟讀取,則會嚴重影響效能,但是如果全部載入到記憶體當中,又有可能造成記憶體溢位,此時使用軟引用可以解決這個問題。
設計思路是:用一個HashMap來儲存圖片的路徑 和 相應圖片物件關聯的軟引用之間的對映關係,在記憶體不足時,JVM會自動回收這些快取圖片物件所佔用的空間,從而有效地避免了OOM的問題。在Android開發中對於大量圖片下載會經常用到