Java 中一共有 4 種類型的引用 : StrongReference、 SoftReference、 WeakReference 以及 PhantomReference (傳說中的幽靈引用).這 4 種類型的引用與 GC 有著密切的關(guān)系, 讓我們逐一來看它們的定義和使用場景 : 1. Strong
Reference StrongReference 是 Java 的默認(rèn)引用實(shí)現(xiàn), 它會盡可能長時(shí)間的存活于 JVM 內(nèi), 當(dāng)沒有任何對象指向它時(shí) GC 執(zhí)行后將會被回收 2.WeakReference WeakReference, 顧名思義, 是一個(gè)弱引用, 當(dāng)所引用的對象在 JVM 內(nèi)不再有強(qiáng)引用時(shí), GC 后 weak reference 將會被自動回收 3.SoftReference SoftReference 于 WeakReference 的特性基本一致, 最大的區(qū)別在于 SoftReference 會盡可能長的保留引用直到 JVM 內(nèi)存不足時(shí)才會被回收(虛擬機(jī)保證), 這一特性使得 SoftReference 非常適合緩存應(yīng)用 4.PhantomReference Phantom Reference(幽靈引用) 與 WeakReference 和 SoftReference 有很大的不同, 因?yàn)樗?/span> get() 方法永遠(yuǎn)返回 null, 這也正是它名字的由來 PhantomReference 唯一的用處就是跟蹤 referent 何時(shí)被 enqueue 到 ReferenceQueue 中. PhantomReference 有兩個(gè)好處: 其一, 它可以讓我們準(zhǔn)確地知道對象何時(shí)被從內(nèi)存中刪除, 這個(gè)特性可以被用于一些特殊的需求中(例如 Distributed GC, XWork 和 google-guice 中也使用 PhantomReference 做了一些清理性工作). 其二, 它可以避免 finalization 帶來的一些根本性問題, 上文提到 PhantomReference 的唯一作用就是跟蹤 referent 何時(shí)被 enqueue 到 ReferenceQueue 中, 但是 WeakReference 也有對應(yīng)的功能, 兩者的區(qū)別到底在哪呢 ? 這就要說到 Object 的 finalize 方法, 此方法將在 gc 執(zhí)行前被調(diào)用, 如果某個(gè)對象重載了 finalize 方法并故意在方法內(nèi)創(chuàng)建本身的強(qiáng)引用, 這將導(dǎo)致這一輪的 GC 無法回收這個(gè)對象并有可能 引起任意次 GC, 最后的結(jié)果就是明明 JVM 內(nèi)有很多 Garbage 卻 OutOfMemory, 使用 PhantomReference 就可以避免這個(gè)問題, 因?yàn)?/span> PhantomReference 是在 finalize 方法執(zhí)行后回收的,也就意味著此時(shí)已經(jīng)不可能拿到原來的引用, 也就不會出現(xiàn)上述問題, 當(dāng)然這是一個(gè)很極端的例子, 一般不會出現(xiàn). Soft vs Weak vs Phantom References(taken from http:///jgloss/phantom.html)
|
|