理解 Java 的 GC 与 幽灵引用

理解 Java 的 GC 与 幽灵引用
转自:http://www.iteye.com/topic/401478 

-------------------------------------------------------------------------------------------------
        Java 中一共有 4 种类型的引用 : StrongReference、 SoftReference、 WeakReference以及 PhantomReference (传说中的幽灵引用 呵呵),
这 4 种类型的引用与 GC 有着密切的关系,  让我们逐一来看它们的定义和使用场景 :

       1. Strong Reference
       
       StrongReference 是 Java 的默认引用实现,  它会尽可能长时间的存活于 JVM内, 当没有任何对象指向它时 GC 执行后将会被回收

Java代码   收藏代码
  1. @Test  
  2. public void strongReference() {  
  3.     Object referent = new Object();  
  4.       
  5.       
  6.     Object strongReference = referent;  
  7.       
  8.     assertSame(referent, strongReference);  
  9.       
  10.     referent = null;  
  11.     System.gc();  
  12.       
  13.       
  14.     assertNotNull(strongReference);  
  15. }  





       2. WeakReference & WeakHashMap

WeakReference, 顾名思义,  是一个弱引用, 当所引用的对象在 JVM 内不再有强引用时, GC 后 weak reference 将会被自动回收

Java代码   收藏代码
  1. @Test  
  2. public void weakReference() {  
  3.     Object referent = new Object();  
  4.     WeakReference weakRerference = new WeakReference(referent);  
  5.   
  6.     assertSame(referent, weakRerference.get());  
  7.       
  8.     referent = null;  
  9.     System.gc();  
  10.       
  11.       
  12.     assertNull(weakRerference.get());  
  13. }  




WeakHashMap 使用 WeakReference 作为 key, 一旦没有指向 key 的强引用, WeakHashMap 在GC 后将自动删除相关的 entry

Java代码   收藏代码
  1. @Test  
  2. public void weakHashMap() throws InterruptedException {  
  3.     Map weakHashMap = new WeakHashMap();  
  4.     Object key = new Object();  
  5.     Object value = new Object();  
  6.     weakHashMap.put(key, value);  
  7.   
  8.     assertTrue(weakHashMap.containsValue(value));  
  9.       
  10.     key = null;  
  11.     System.gc();  
  12.       
  13.       
  14.     Thread.sleep(1000);  
  15.       
  16.       
  17.     assertFalse(weakHashMap.containsValue(value));  
  18. }  




       3. SoftReference

SoftReference 于 WeakReference 的特性基本一致, 最大的区别在于 SoftReference会尽可能长的保留引用直到 JVM 内存不足时才会被回收(虚拟机保证), 这一特性使得 SoftReference非常适合缓存应用

Java代码   收藏代码
  1. @Test  
  2. public void softReference() {  
  3.     Object referent = new Object();  
  4.     SoftReference softRerference = new SoftReference(referent);  
  5.   
  6.     assertNotNull(softRerference.get());  
  7.       
  8.     referent = null;  
  9.     System.gc();  
  10.       
  11.       
  12.     assertNotNull(softRerference.get());  
  13. }  




       4. PhantomReference

       作为本文主角, Phantom Reference(幽灵引用) 与 WeakReference 和 SoftReference有很大的不同,  因为它的 get() 方法永远返回 null, 这也正是它名字的由来

Java代码   收藏代码
  1. @Test  
  2. public void phantomReferenceAlwaysNull() {  
  3.     Object referent = new Object();  
  4.     PhantomReference phantomReference = new PhantomReference(referent, new ReferenceQueue());  
  5.       
  6.       
  7.     assertNull(phantomReference.get());  
  8. }  



        诸位可能要问, 一个永远返回 null 的 reference 要来何用,  请注意构造PhantomReference 时的第二个参数 ReferenceQueue(事实上 WeakReference &SoftReference 也可以有这个参数),
PhantomReference 唯一的用处就是跟踪 referent  何时被 enqueue 到ReferenceQueue 中.

    5. RererenceQueue

当一个 WeakReference 开始返回 null 时, 它所指向的对象已经准备被回收,这时可以做一些合适的清理工作.   将一个ReferenceQueue 传给一个 Reference 的构造函数, 当对象被回收时, 虚拟机会自动将这个对象插入到ReferenceQueue 中, WeakHashMap 就是利用 ReferenceQueue 来清除 key 已经没有强引用的entries.

Java代码   收藏代码
  1. @Test  
  2. public void referenceQueue() throws InterruptedException {  
  3.     Object referent = new Object();       
  4.     ReferenceQueue referenceQueue = new ReferenceQueue();  
  5.     WeakReference weakReference = new WeakReference(referent, referenceQueue);  
  6.       
  7.     assertFalse(weakReference.isEnqueued());  
  8.     Reference

你可能感兴趣的:(理解 Java 的 GC 与 幽灵引用)