java Reference
10391 ワード
関連解説、参考:
Java Referenceソースの分析
Java Reference詳細
Reference:
Java Referenceソースの分析
Java Reference詳細
Reference:
// :Reference ,Referent
/**
* Reference , 。
* , , ;
*
* @since 1.2
*/
public abstract class Reference {
/*
* Reference 4 :
*
* 1.Active:Active Reference GC , GC (appropriate)
* , Pending Inactive;
* ReferenceQueue, Pendging , pending-Reference list;
* Inactive ; Reference Active ;
* ,queue = ReferenceQueue ReferenceQueue.NULL; next = null;
*
* 2.Pending: pending-Reference list , Reference-handler
* ReferenceQueue ;
* ,queue = ReferenceQueue; next = queue ;
*
* 3.Enqueued: ReferenceQueue . ReferenceQueue Inactive ;
* ,queue = ReferenceQueue.ENQUEUED; next = queue ;
*
* 4.Inactive: Inactive, ;
* queue = ReferenceQueue.NULL; next = this.
*/
// Reference ReferenceQueue.NULL, Active Inactive
// reference
private T referent; /* Treated specially by GC */
ReferenceQueue super T> queue;
Reference next;
transient private Reference discovered; /* used by VM */
static private class Lock {
};
private static Lock lock = new Lock();
// JVM , Reference referent , ReferenceQueue ,
// JVM Reference pending , ReferenceQueue ;
// ReferenceHandler reference, ReferenceQueue ;
// lock
private static Reference pending = null;
// , pending reference ReferenceQueue
private static class ReferenceHandler extends Thread {
ReferenceHandler(ThreadGroup g, String name) {
super(g, name);
}
public void run() {
for (;;) {
Reference r;
synchronized (lock) {
// pending list ,
if (pending != null) {
r = pending;
Reference rn = r.next;
// pending
pending = (rn == r) ? null : rn;
// next
r.next = r;
} else {
try {
// ,
lock.wait();
} catch (InterruptedException x) {
}
// ,
continue;
}
}
// Fast path for cleaners
if (r instanceof Cleaner) {
((Cleaner) r).clean();
continue;
}
// pending list reference ReferenceQueue
ReferenceQueue q = r.queue;
if (q != ReferenceQueue.NULL)
q.enqueue(r);
}
}
}
// ReferenceHandler
static {
ThreadGroup tg = Thread.currentThread().getThreadGroup();
for (ThreadGroup tgn = tg; tgn != null; tg = tgn, tgn = tg.getParent())
;
Thread handler = new ReferenceHandler(tg, "Reference Handler");
handler.setPriority(Thread.MAX_PRIORITY);
handler.setDaemon(true);
handler.start();
}
/* -- Referent accessor and setters -- */
// Reference , , null
public T get() {
return this.referent;
}
// ; reference ;
// gc referent null, .
public void clear() {
this.referent = null;
}
/* -- Queue operations -- */
public boolean isEnqueued() {
synchronized (this) {
return (this.queue != ReferenceQueue.NULL) && (this.next != null);
}
}
public boolean enqueue() {
return this.queue.enqueue(this);
}
/* -- Constructors -- */
Reference(T referent) {
this(referent, null);
}
Reference(T referent, ReferenceQueue super T> queue) {
this.referent = referent;
// ReferenceQueue.NULL
this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
}
}
ReferenceQue:/**
* Reference queues, Reference (appropriate) ,
* ReferenceQueue 。
* : ,LIFO; , ;
* Reference ;
*
* @since 1.2
*/
public class ReferenceQueue {
public ReferenceQueue() {
}
private static class Null extends ReferenceQueue {
boolean enqueue(Reference extends S> r) {
return false;
}
}
// Reference queue null , NULL
static ReferenceQueue
SoftReference:/**
* SoftReference , GC ; Soft
* (memory-sensitive) (cache);
* OOM , softly-reachable ;
* (bias against)
* (recently-created) (recently-used) soft references
* ;
*
* @since 1.2
*/
public class SoftReference extends Reference {
//
static private long clock;
// get() , ( )
// softreference
private long timestamp;
public SoftReference(T referent) {
super(referent);
this.timestamp = clock;
}
public SoftReference(T referent, ReferenceQueue super T> q) {
super(referent, q);
this.timestamp = clock;
}
public T get() {
T o = super.get();
if (o != null && this.timestamp != clock)
this.timestamp = clock;
return o;
}
}
Weak Reference:/**
* weakreference GC ;
* weakly reachable, weakreference referencequeue
* @since 1.2
*/
public class WeakReference extends Reference {
public WeakReference(T referent) {
super(referent);
}
public WeakReference(T referent, ReferenceQueue super T> q) {
super(referent, q);
}
}
PhotomReference:/**
* referent , PhantomReference ReferenceQueue
* Unlike soft and weak references, phantom references are not
* automatically cleared by the garbage collector as they are enqueued. An
* object that is reachable via phantom references will remain so until all
* such references are cleared or themselves become unreachable.
* @since 1.2
*/
// , GC , ,
// phantom /'fæntəm/ : ; ; ; ; ;
// You know it is somewhere,but you never know where
// ,
public class PhantomReference extends Reference {
// get() null
public T get() {
return null;
}
// PhantomReference ReferenceQueue
// queue null, PhantomReference (completely useless)
public PhantomReference(T referent, ReferenceQueue super T> q) {
super(referent, q);
}
}