java.lang.ref.Reference<T>,java引用对象及垃圾收集器的工具类

こ雲淡風輕ζ 提交于 2019-12-01 03:58:08

等下会以英文源文档+翻译的方式来分析Reference这一个类。

约定对应的中文翻译对对应于正上面的英文或者代码,英文源文档直接对应于正上面的代码。

>类的定义

 Abstract base class for reference objects.  This class defines the

 operations common to all reference objects. Because reference objects are

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

 not be subclassed directly.


从JDK中文文档的翻译是:

引用对象的抽象基类。此类定义了常用于所有引用对象的操作。因为引用对象是通过与垃圾回收器的密切合作来实现的,所以不能直接为此类创建子类。 

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

/* 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是如何应用到我们的代码中的,我们将会在后面来分析。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!