天天看點

Java的四種引用和回收政策

參考:

Java Reference詳解 .

這篇講的很清楚!!了解這些引用類型 注意一點,當JVM回收時,如果有回收引用隊列queue,會把回收的referent加入到回收隊列中。進而可實作對象回收時的通知,進行一定的工作。如WeakHashMap(用于回收key為null的entry) , DirectByteBuffer中的cleaner(用于回收堆外記憶體,因為堆外記憶體的回收不由JVM管理。)

Java中的強引用,軟引用,弱引用,虛引用有什麼用?

《Effective Java》中正常是不建議使用這些引用Finalizer或者Cleaner來回收對象的,因為回收線程優先級不夠高,回收不夠及時,可能會導緻嚴重的GC問題。如果想手動管理對象的回收,可以使類實作AutoCloseable接口,當需要釋放對象的時候使用戶端調用close方法。

弱引用的Java應用:

ThreadLocal(ThreadLocalMap.Entry中key為弱引用,這樣如果key為null的話,有些方法如resize會清空entry中的value,垃圾回收的時候就會回收該entry)

static class ThreadLocalMap {

        /**
         * The entries in this hash map extend WeakReference, using
         * its main ref field as the key (which is always a
         * ThreadLocal object).  Note that null keys (i.e. entry.get()
         * == null) mean that the key is no longer referenced, so the
         * entry can be expunged from table.  Such entries are referred to
         * as "stale entries" in the code that follows.
         */
        static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }           

複制

WeakHashMap(key為弱引用的HashMap)

軟引用的Java應用:

//Class中的緩存
   private volatile transient SoftReference<ReflectionData<T>> reflectionData;

    // Incremented by the VM on each call to JVM TI RedefineClasses()
    // that redefines this class or a superclass.
    private volatile transient int classRedefinedCount = 0;

    // Lazily create and cache ReflectionData
    private ReflectionData<T> reflectionData() {
        SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
        int classRedefinedCount = this.classRedefinedCount;
        ReflectionData<T> rd;
        if (useCaches &&
            reflectionData != null &&
            (rd = reflectionData.get()) != null &&
            rd.redefinedCount == classRedefinedCount) {
            return rd;
        }
        // else no SoftReference or cleared SoftReference or stale ReflectionData
        // -> create and replace new instance
        return newReflectionData(reflectionData, classRedefinedCount);
    }           

複制

其實SoftReference和WeakReference都經常用來作為緩存來使用,不過WeakReference更容易被清除而已。

Java的守護線程參考:

從Daemons到finalize timed out after 10 seconds