首页  

四种引用及WeakHashMap介绍     所属分类 java 浏览量 1316
强引用 
软引用 
弱引用 
虚引用

软引用 SoftReference

Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue();
SoftReference reference = new SoftReference(obj, queue);
obj = null;


内存不足时,软引用对象被回收,reference.get()为nul,
软引用对象 添加进ReferenceQueue 队列中

SoftReference ref = null;
while ((ref = (SoftReference) queue.poll()) != null) {
            //清除软引用对象
}

弱引用(WeakReference)
GC时就被回收

WeakReference reference = new WeakReference(obj, queue);

虚引用(PhantomReference)
PhantomReference reference = new PhantomReference(obj, queue);

WeakHashMap 要点

ReferenceQueue和WeakReference
当key值没有强引用的时候,从WeakHashMap里移除。



private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> {
        Entry(Object key, V value,
              ReferenceQueue<Object> queue,
              int hash, Entry<K,V> next) {
              super(key, queue);
              this.value = value;
              this.hash  = hash;
              this.next  = next;
        }
    ...
}


Entry继承自WeakReference;
Entry本身没有保存key值,而是把key作为WeakReference的引用对象交给了super构造。Entry是个针对key值的弱引用。


一般都会继承 SoftReference 或 WeakReference ,在里面放一些上下文信息,
譬如 可以  把value  作为 弱引用, 并记录相应的key , 回收时 remove key 



expungStaleEntries()   实现对 Entry的删除


private void expungeStaleEntries() {
        //遍历引用队列,找到每一个被GC收集的对象
        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;
                        //帮助GC执行
                        e.value = null;
                        // size 减一 !!!
                        size--;
                        break;
                    }
                    prev = p;
                    p = next;
                }
            }
        }
}



expungStaleEntries()方法在resize、put、get、forEach方法里调用。

上一篇     下一篇
基于数据库的分布式锁设计

prometheus集成grafana实现可视化

g1 GC 要点

软引用弱引用及引用队列实战例子

grafana基本概念

跨域资源共享CORS介绍