1. 程式人生 > 實用技巧 >Java WeakReference介紹和分析

Java WeakReference介紹和分析

1.概述

在Java裡, 當一個物件o被建立時, 它被放在Heap裡. 當GC執行的時候, 如果發現沒有任何引用指向o, o就會被回收以騰出記憶體空間. 或者換句話說, 一個物件被回收, 必須滿足兩個條件: 1)沒有任何引用指向它 2)GC被執行.

在現實情況寫程式碼的時候, 我們往往通過把所有指向某個物件的referece置空來保證這個物件在下次GC執行的時候被回收。

但是, 手動置空物件對於程式設計師來說, 是一件繁瑣且違背自動回收的理念的.對於簡單的情況, 手動置空是不需要程式設計師來做的, 因為在java中, 對於簡單物件, 當呼叫它的方法執行完畢後, 指向它的引用會被從stack中popup, 所以他就能在下一次GC執行時被回收了.

但是, 也有特殊例外. 當使用cache的時候, 由於cache的物件正是程式執行需要的, 那麼只要程式正在執行, cache中的引用就不會被GC給(或者說, cache中的reference擁有了和主程式一樣的life cycle). 那麼隨著cache中的reference越來越多, GC無法回收的object也越來越多, 無法被自動回收. 當這些object需要被回收時, 回收這些object的任務只有交給程式編寫者了. 然而這卻違背了GC的本質(自動回收可以回收的objects).

所以, java中引入了weak reference.

當一個物件僅僅被weak reference(弱引用)指向, 而沒有任何其他strong reference(強引用)指向的時候, 如果這時GC執行, 那麼這個物件就會被回收,不論當前的記憶體空間是否足夠,這個物件都會被回收。

2.使用

Java程式碼
  1. Objectc=newCar();//只要c還指向carobject,carobject就不會被回收

當一個物件僅僅被weak reference指向, 而沒有任何其他strong reference指向的時候, 如果GC執行, 那麼這個物件就會被回收. weak reference的語法是:

Java程式碼
  1. WeakReference<Car>weakCar=newWeakReference(Car)(car);

當要獲得weak reference引用的object時, 首先需要判斷它是否已經被回收:

Java程式碼
  1. weakCar.get();

如果此方法為空, 那麼說明weakCar指向的物件已經被回收了.

WeakReference原始碼

public class WeakReference<T> extends Reference<T> {

    /**
     * Creates a new weak reference that refers to the given object.  The new
     * reference is not registered with any queue.
     *
     * @param referent object the new weak reference will refer to
     */
    public WeakReference(T referent) {
        super(referent);
    }

    /**
     * Creates a new weak reference that refers to the given object and is
     * registered with the given queue.
     *
     * @param referent object the new weak reference will refer to
     * @param q the queue with which the reference is to be registered,
     *          or <tt>null</tt> if registration is not required
     */
    public WeakReference(T referent, ReferenceQueue<? super T> q) {
        super(referent, q);
    }

}

因為WeakRefernce引用的物件回收後,WeakReference本身沒有釋放,因此可以通過ReferenceQueue來儲存釋放的WeakReference。