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 |