Reference ReferenceQue WeakhashMap詳細

6377 ワード

強引用
Object o=new Object()
oは強い引用です。強い引用はVM GCではありません。メモリが足りなくてもOutOfMemoryErrorは回収されません。
ソフト参照
/**対象が到達できなくなってから、メモリが足りない時まで回収されます。

public class SoftReference<T> extends Reference<T> {...}
弱い引用
/**対象が到達できない場合、gc運転は回収されます。

public class WeakReference<T> extends Reference<T> {...}
虚引用
//まだ分かりません。構造はReferenceQue*/を伝えなければなりません。

public class PhantomReference<T> extends Reference<T> {
...
    public T get() {//  PhantomReference get  ,         null,       ,,,      
        return null;
    }
} 
WeakhashMapもあります。その後に追加します。
Reference自体はチェーンのデータ構造で、次の二つのフィールドがあります。

private T referent;
Reference next;
Referenceには静的なpendingフィールドがあります。

private static Reference pending = null;
vmは到達不可能なReferenceオブジェクトをpendingチェーンにかける(VM実現);
ReferenceにはReferenceHandlerというhandlerがあります。
静的な高速で初期化します。
機能は循環の訪問pendingで、pendingの中の達成できない対象を入隊します。
Reference&ReferenceQueの関係:
ReferenceにはReferenceQueの引用があり、ReferenceにはReferenceQueの引用があり、Referenceの構造方法で初期化されています。
指定されていない場合は、全体的なデフォルトのqueueに入ることができますが、このデフォルトのqueueですが、このqueueは実際の入力操作がありません。
構造的なqueueが入ってきたら、到達できないオブジェクトが入隊します。

class ReferenceQueue<T>{
    //      ReferenceQueue 
    static ReferenceQueue NULL = new Null();//   ReferenceQueue
    static ReferenceQueue ENQUEUED = new Null();
	private static class Null extends ReferenceQueue {
        boolean enqueue(Reference r) {//Null  enqueue()         
            return false;
        }
    }

    boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
        synchronized (r) {
            if (r.queue == ENQUEUED) return false;
            synchronized (lock) {
                r.queue = ENQUEUED;
                r.next = (head == null) ? r : head;
                head = r;
                queueLength++;
                if (r instanceof FinalReference) {
                    sun.misc.VM.addFinalRefCount(1);
                }
                lock.notifyAll();
                return true;
            }
        }
    }
}

public abstract class Reference<T>{
    ...
	private T referent;//      (     )
	
	ReferenceQueue<? super T> queue;

	/*(     ):pending  jvm    ,
           Reference   referent          ,
          jvm  Reference    pending  */
	private static Reference pending = null; /* used by VM */
	...
       /*    ,    queue ,
             referent(pending Reference   )   queue */
	private static class ReferenceHandler extends Thread{

        ReferenceHandler(ThreadGroup g, String name) {
            super(g, name);
        }
        public void run() {
            for (;;) {// pending   
			...
            }
        }
	
	static { //       :ReferenceHandler
        ThreadGroup tg = Thread.currentThread().getThreadGroup();
        for (ThreadGroup tgn = tg;
             tgn != null;
             tg = tgn, tgn = tg.getParent());
        Thread handler = new ReferenceHandler(tg, "Reference Handler");
        /* If there were a special system-only priority greater than
         * MAX_PRIORITY, it would be used here
         */
        handler.setPriority(Thread.MAX_PRIORITY);
        handler.setDaemon(true);
        handler.start();
    }
	/**
     * Adds this reference object to the queue with which it is registered,
     * if any.*/
	public boolean enqueue() {
        return this.queue.enqueue(this);
    }
	...
}
次はWeakhashMapです。

public class WeakHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V> {
....
    /* WeakHashMap          NULL ReferenceQueue*/
    /*WeakHashMap       ReferenceQueue  “   ”               key */
	private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
	
	/*   ,  ,  WeakReference,        */
	private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> {
	    V value;
        int hash;
        Entry<K,V> next;
	    Entry(Object key, V value,ReferenceQueue<Object> queue,
              int hash, Entry<K,V> next) {
			/* key   WeakReference   private T referent; 
			  WeakHashMap key    ,  value      ,
			          expungeStaleEntries(),value    
			      */
            super(key, queue);
            this.value = value;
            this.hash  = hash;
            this.next  = next;
        }
	....
	}
	
    /*     */
    private void expungeStaleEntries() {
        for (Object x; (x = queue.poll()) != null; ) {
            synchronized (queue) {
                @SuppressWarnings("unchecked")
                    Entry<K,V> e = (Entry<K,V>) x;
                int i = indexFor(e.hash, table.length);

                Entry<K,V> prev = table[i];
                Entry<K,V> p = prev;
                while (p != null) {
                    Entry<K,V> next = p.next;
                    if (p == e) {
                        if (prev == e)
                            table[i] = next;
                        else
                            prev.next = next;
                        // Must not null out e.next;
                        // stale entries may be in use by a HashIterator
                        e.value = null; // Help GC
                        size--;
                        break;
                    }
                    prev = p;
                    p = next;
                }
            }
        }
    }
}