Reference ReferenceQue WeakhashMap詳細
強引用
Object o=new Object()
oは強い引用です。強い引用はVM GCではありません。メモリが足りなくてもOutOfMemoryErrorは回収されません。
ソフト参照
/**対象が到達できなくなってから、メモリが足りない時まで回収されます。
/**対象が到達できない場合、gc運転は回収されます。
//まだ分かりません。構造はReferenceQue*/を伝えなければなりません。
Reference自体はチェーンのデータ構造で、次の二つのフィールドがあります。
ReferenceにはReferenceHandlerというhandlerがあります。
静的な高速で初期化します。
機能は循環の訪問pendingで、pendingの中の達成できない対象を入隊します。
Reference&ReferenceQueの関係:
ReferenceにはReferenceQueの引用があり、ReferenceにはReferenceQueの引用があり、Referenceの構造方法で初期化されています。
指定されていない場合は、全体的なデフォルトのqueueに入ることができますが、このデフォルトのqueueですが、このqueueは実際の入力操作がありません。
構造的なqueueが入ってきたら、到達できないオブジェクトが入隊します。
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;
}
}
}
}
}