java.lang.ref.Reference,java引用對象及垃圾收集器的工具類

等下會以英文源文檔+翻譯的方式來分析Reference這一個類。app

約定對應的中文翻譯對對應於正上面的英文或者代碼,英文源文檔直接對應於正上面的代碼。oop

>類的定義ui

 Abstract base class for reference objects.  This class defines thethis

 operations common to all reference objects. Because reference objects are編碼

 implemented in close cooperation with the garbage collector, this class mayspa

 not be subclassed directly.線程


從JDK中文文檔的翻譯是:翻譯

引用對象的抽象基類。此類定義了經常使用於全部引用對象的操做。由於引用對象是經過與垃圾回收器的密切合做來實現的,因此不能直接爲此類建立子類。 code

>private T referent; /* Treated specially by GC */orm

/* A Reference instance is in one of four possible internal states:

     *

     *   Active: Subject to special treatment by the garbage collector.  Some

     *   time after the collector detects that the reachability of the

     *   referent has changed to the appropriate state, it changes the

     *   instance's state to either Pending or Inactive, depending upon

     *   whether or not the instance was registered with a queue when it was

     *   created.  In the former case it also adds the instance to the

     *   pending-Reference list.  Newly-created instances are Active.

     *

     *   Pending: An element of the pending-Reference list, waiting to be

     *   enqueued by the Reference-handler thread.  Unregistered instances

     *   are never in this state.

     *

     *   Enqueued: An element of the queue with which the instance was

     *   registered when it was created.  When an instance is removed from

     *   its ReferenceQueue, it is made Inactive.  Unregistered instances are

     *   never in this state.

     *

     *   Inactive: Nothing more to do.  Once an instance becomes Inactive its

     *   state will never change again.

     *

     * The state is encoded in the queue and next fields as follows:

     *

     *   Active: queue = ReferenceQueue with which instance is registered, or

     *   ReferenceQueue.NULL if it was not registered with a queue; next =

     *   null.

     *

     *   Pending: queue = ReferenceQueue with which instance is registered;

     *   next = Following instance in queue, or this if at end of list.

     *

     *   Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance

     *   in queue, or this if at end of list.

     *

     *   Inactive: queue = ReferenceQueue.NULL; next = this.

     *

     * With this scheme the collector need only examine the next field in order

     * to determine whether a Reference instance requires special treatment: If

     * the next field is null then the instance is active; if it is non-null,

     * then the collector should treat the instance normally.

     * 

     * To ensure that concurrent collector can discover active Reference 

     * objects without interfering with application threads that may apply 

     * the enqueue() method to those objects, collectors should link 

     * discovered objects through the discovered field.

     */

中文翻譯:

一個引用實例是下面四種可能狀態之一:

active:此狀態由垃圾收集器特殊處理。在收集器檢測到此引用的可達性變道其餘合適狀態以後,根據此實例是否在建立的時候註冊到一個隊列中來將他置爲"pending"或者"inactive狀態"。若是是前一個,把此實例加入到「pending-Reference"列表。新建立的實例的狀態是"active"。

pending:「pending-Reference"列表中的一個元素,等待被"Reference-handler"線程出列。非註冊過的實例不會出如今此狀態中。

enqueued:建立的時候註冊到隊列的元素。當其實例從"ReferenceQueue"中移除的時候,就會變成"inactive"狀態。非註冊過的實例不會出如今此狀態中。

inactive:什麼都沒有。一旦實例變成"inactive"狀態,其狀態將再也不變化。

狀態按以下方式在隊列和下一個域中進行編碼:

active:queue=其建立時候所註冊的ReferenceQueue,當其爲註冊到隊列,queue=ReferenceQueue.NULL;next=null。

pending:queue=其建立時候所註冊的ReferenceQueue,next=隊列中的下一個實例,若是已到達隊列末,則爲本身。

enqueue:queue=Reference.ENQUEUE;next=隊列中的下一個實例,若是已到達隊列末,則爲本身。

inactive:queue=ReferenceQueue.NULL;next=this。

根據這種方案,收集器只須要經過檢測下一個域來決定引用實例是否須要特殊處理。若是next是null,則此此示例狀態爲"active";若非null,則收集器正常處理此示例。

爲確保在發收集器能夠在不干擾到可能正對那些引用對象調用enqueue()方法的應用線程的同時發現"active"引用對象,收集器應該經過"discovered field"連接到"discovered objects"。

>ReferenceQueue<? super T> queue;

>Reference next;

>transient private Reference<T> discovered; /* used by VM */

>static private class Lock { };

英文:

/* Object used to synchronize with the garbage collector.  The collector

     * must acquire this lock at the beginning of each collection cycle.  It is

     * therefore critical that any code holding this lock complete as quickly

     * as possible, allocate no new objects, and avoid calling user code.

     */

中文翻譯:

用於與垃圾收集器進行同步的對象。收集器會在每一次垃圾回收的開始獲取該鎖。所以取得此鎖的對象應該儘快的完成、不分配新對象和避免調用用戶代碼。

>private static Lock lock = new Lock();

>private static Reference pending = null;

英文:

/* List of References waiting to be enqueued.  The collector adds

     * References to this list, while the Reference-handler thread removes

     * them.  This list is protected by the above lock object.

     */

中文:

等待被入列的引用列表。收集器添加引用到此列表,"Reference-handler"線程今後列表中移除他們。此列表由上邊的鎖保護。

>代碼:

private static class ReferenceHandler extends Thread {

ReferenceHandler(ThreadGroup g, String name) {

super(g, name);

}

public void run() {

for (;;) {

Reference r;

synchronized (lock) {

if (pending != null) {

r = pending;

Reference rn = r.next;

pending = (rn == r) ? null : rn;

r.next = r;

} else {

try {

lock.wait();

} catch (InterruptedException x) {

}

continue;

}

}

// Fast path for cleaners

if (r instanceof Cleaner) {

((Cleaner) r).clean();

continue;

}

ReferenceQueue q = r.queue;

if (q != ReferenceQueue.NULL)

q.enqueue(r);

}

}

}

英文:

/* High-priority thread to enqueue pending References

     */

中文註釋:

永遠將"pending"的引用入列的高優先級線程。

>

static {

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

    }

中文註釋:

若是有比MAX_PRIORITY更高的指定系統優先級,那麼在這裏使用他。

>代碼

public void clear() {

this.referent = null;

    }

英文:

/**

     * Clears this reference object.  Invoking this method will not cause this

     * object to be enqueued.

     *

     * <p> This method is invoked only by Java code; when the garbage collector

     * clears references it does so directly, without invoking this method.

     */

中文翻譯:

清除此引用對象。調用此方法不會將此對象出列。此方法僅能由Java方法調用;當垃圾收集器處理引用的時候會直接清除掉,沒必要調用此方法。    

從上面能夠發現Java的垃圾收集器是如何根據Reference來進行垃圾回收的。但Reference是如何應用到咱們的代碼中的,咱們將會在後面來分析。

相關文章
相關標籤/搜索