Reference ReferenceQueue详解_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Reference ReferenceQueue详解

Reference ReferenceQueue详解

 2014/10/29 21:17:38  shifulong  程序员俱乐部  我要评论(0)
  • 摘要:强引用Objecto=newObject();o就是一个强引用,强引用不会被VMGC,即使内存不够抛出OutOfMemoryError也不会被回收软引用/**对象不可达之后,一直到内存不足时,才被回收*/publicclassSoftReference<T>extendsReference<T>{...}弱引用/**对象不可达之后,gc运行就会被回收*/publicclassWeakReference<T>extendsReference<T>{
  • 标签:详解
强引用
Object o = new Object();
o就是一个强引用, 强引用不会被VM GC, 即使内存不够抛出OutOfMemoryError也不会被回收

软引用
/**对象不可达之后,一直到内存不足时,才被回收*/
class="java" name="code">
public class SoftReference<T> extends Reference<T> {...}

弱引用
/**对象不可达之后,gc运行就会被回收*/
public class WeakReference<T> extends Reference<T> {...}

虚引用
/**还没搞懂,构造的时候必须传一个ReferenceQueue*/
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(Thread[Daemon线程]),
在一个静态快中初始化,
功能就是循环的访问pending,将pending中的不可达对象 入队(enqueue);

Reference & ReferenceQueue的关系:
Reference存在一个ReferenceQueue的引用,Reference存在一个ReferenceQueue的引用是在Reference的构造方法中初始化的,
如果没有指定,会传入一个全局默认的queue但是这个默认的queue,但是这个queue 没有实际的入队操作(见下面源码),
如果传入一个构造的queue,不可达的对象会入队(enqueue)
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);
    }
	...
}
上一篇: 谷歌钱包高管再创业 要把POS机“革命” 下一篇: 没有下一篇了!
发表评论
用户名: 匿名