WeakReference源碼解析

1.簡(jiǎn)介

 Weak reference objects, which do not prevent their referents from being
 made finalizable, finalized, and then reclaimed.  Weak references are most
 often used to implement canonicalizing mappings.

弱引用不會(huì)阻止其引用的對(duì)象被終止和回收,弱引用最常用于實(shí)現(xiàn)規(guī)范化映射。

規(guī)范化映射:a canonicalizing mapping in order to prevent loading the same entity from the database more than once.

參考WeakHashMap相似的介紹
This class is intended primarily for use with key objects whose equals methods test for object identity using the == operator. Once such a key is discarded it can never be recreated, so it is impossible to do a lookup of that key in a WeakHashMap at some later time and be surprised that its entry has been removed. This class will work perfectly well with key objects whose equals methods are not based upon object identity, such as String instances. With such recreatable key objects, however, the automatic removal of WeakHashMap entries whose keys have been discarded may prove to be confusing.

 <p> Suppose that the garbage collector determines at a certain point in time
 that an object is <a href="package-summary.html#reachability">weakly
 reachable</a>.  At that time it will atomically clear all weak references to
 that object and all weak references to any other weakly-reachable objects
 from which that object is reachable through a chain of strong and soft
 references.  At the same time it will declare all of the formerly
 weakly-reachable objects to be finalizable.  At the same time or at some
 later time it will enqueue those newly-cleared weak references that are
 registered with reference queues.

確定弱引用只是弱可達(dá)后,就可以原子地進(jìn)行回收。并且可以將已經(jīng)回收的弱引用放到創(chuàng)建時(shí)注冊(cè)的reference queues中。

2.只有構(gòu)造器

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);
    }

}

3.實(shí)例

public class WeakReferenceWhenIdle {
    public static class House {

    }

    public static void main(String[] args) {
        House seller = new House();
        WeakReference<House> buyer = new WeakReference<>(seller, new ReferenceQueue<>());
        seller = null;

        long start = System.nanoTime();
        int count = 0;
        while (true) {
            if (buyer.get() == null) {
                long duration = (System.nanoTime() - start) / (1000 * 1000);
                System.out.println("house is null and existed time = " + duration + "ms");
                break;
            } else {
                    System.out.println("still there. count = " + (count));
                count++;
            }
        }
    }
}

-XX:+PrintGCDetails打開GC日志:

[GC (Allocation Failure) [PSYoungGen: 33280K->760K(38400K)] 33280K->768K(125952K), 0.0007046 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 38400K, used 1752K [0x00000000d5a00000, 0x00000000d8480000, 0x0000000100000000)
  eden space 33280K, 2% used [0x00000000d5a00000,0x00000000d5af8000,0x00000000d7a80000)
  from space 5120K, 14% used [0x00000000d7a80000,0x00000000d7b3e030,0x00000000d7f80000)
  to   space 5120K, 0% used [0x00000000d7f80000,0x00000000d7f80000,0x00000000d8480000)
 ParOldGen       total 87552K, used 8K [0x0000000080e00000, 0x0000000086380000, 0x00000000d5a00000)
  object space 87552K, 0% used [0x0000000080e00000,0x0000000080e02000,0x0000000086380000)
 Metaspace       used 3491K, capacity 4500K, committed 4864K, reserved 1056768K
  class space    used 376K, capacity 388K, committed 512K, reserved 1048576K

house is null and existed time = 361ms

4.應(yīng)用場(chǎng)景

一般來說,很少直接使用WeakReference,而是使用WeakHashMap。在WeakHashMap中,內(nèi)部有一個(gè)引用隊(duì)列,插入的元素會(huì)被包裹成WeakReference,并加入隊(duì)列中,用來做緩存再合適不過。

在Tomcat的緩存ConcurrentCache中,其實(shí)就用到了WeakHashMap。使用ConcurrentHashMap和WeakHashMap做了類似分代緩存的操作

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容