StrongReference是Java的默認引用實現,它會盡量長時間的存活於JVM內,當沒有任何對象指向它時GC執行後將會被回收 html
public void strongReference() { Object referent = new Object(); // 經過賦值建立 StrongReference Object strongReference = referent; assertSame(referent, strongReference); referent = null; System.gc(); // StrongReference 在 GC 後不會被回收 assertNotNull(strongReference); }
public void weakReference() { Object referent = new Object(); WeakReference<Object> weakRerference = new WeakReference<Object>(referent); assertSame(referent, weakRerference.get()); referent = null; System.gc(); // 一旦沒有指向 referent 的強引用, weak reference 在 GC 後會被自動回 assertNull(weakRerference.get()); }WeakHashMap使用WeakReference做爲key,一旦沒有指向key的強引用,WeakHashMap在GC後將自動刪除相關的entry
public void weakHashMap() throws InterruptedException { Map<Object, Object> weakHashMap = new WeakHashMap<Object, Object>(); Object key = new Object(); Object value = new Object(); weakHashMap.put(key, value); assertTrue(weakHashMap.containsValue(value)); key = null; System.gc(); // 等待無效 entries 進入 ReferenceQueue 以便下一次調用 getTable 時被清理 Thread.sleep(1000); // 一旦沒有指向 key 的強引用, WeakHashMap 在 GC 後將自動刪除相關的 entry assertFalse(weakHashMap.containsValue(value)); }
public void softReference() { Object referent = new Object(); SoftReference<Object> softRerference = new SoftReference<Object>(referent); assertNotNull(softRerference.get()); referent = null; System.gc(); // soft references 只有在 jvm OutOfMemory 以前纔會被回收, 因此它很是適合緩存應用 assertNotNull(softRerference.get()); }
public void phantomReferenceAlwaysNull() { Object referent = new Object(); PhantomReference<Object> phantomReference = new PhantomReference<Object>(referent, new ReferenceQueue<Object>()); // phantom reference 的 get 方法永遠返回 null assertNull(phantomReference.get()); }諸位可能要問,一個永遠返回null的reference要來何用,請注意構造PhantomReference時的第二個參數ReferenceQueue(事實上WeakReference&SoftReference也能夠有這個參數),PhantomReference惟一的用處就是跟蹤referent什麼時候被enqueue到ReferenceQueue中.
public void referenceQueue() throws InterruptedException { Object referent = new Object(); ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>(); WeakReference<Object> weakReference = new WeakReference<Object>(referent, referenceQueue); assertFalse(weakReference.isEnqueued()); Reference<? extends Object> polled = referenceQueue.poll(); assertNull(polled); referent = null; System.gc(); assertTrue(weakReference.isEnqueued()); Reference<? extends Object> removed = referenceQueue.remove(); assertNotNull(removed); }
Strong Reference |
An ordinary reference. Keeps objects alive as long as they are referenced. |
normal reference. |
Any object not pointed to can be reclaimed. |
default |
Soft Reference |
Keeps objects alive provided there’s enough memory. |
to keep objects alive even after clients have removed their references (memory-sensitive caches), in case clients start asking for them again by key. |
After a first gc pass, the JVM decides it still needs to reclaim more space. |
java.lang.ref.SoftReference |
Weak Reference |
Keeps objects alive only while they’re in use (reachable) by clients. |
Containers that automatically delete objects no longer in use. |
After gc determines the object is only weakly reachable |
java.lang.ref.WeakReference java.util.WeakHashMap |
Phantom Reference | Lets you clean up after finalization but before the space is reclaimed (replaces or augments the use offinalize()) | Special clean up processing |
After finalization. |
java.lang.ref.PhantomReference |