java四种引用

    xiaoxiao2021-03-25  101

    分别有强引用、软引用、弱引用、虚引用,分别对应Object a = new Object();、SoftReference、WeakReference、PhantomReference。

    其中:

    1、强引用:引用存在,就不会被GC回收。

    2、软引用:引用存在,当堆发生out of memory时会被回收其内存空间,当然回收后内存够用了就不再抛出了。

    3、弱引用:GC时就一定会回收其内存。假设某service内部变量是弱引用,存放一些查询的数据,两个线程同时过来拿数据,则只需要一次查询就行了,使用完就为null被GC了,下次请求再初始化一次数据(具体实现有待思考...)。

    4、虚引用:任何时候都能被回收,不会影响对象生命周期。

    其中,后面三种引用都继承了Reference虚拟类,其在class加载时调用static会开启一个线程,将等待GC回收对象时,调用enqueue当前弱引用对象放入queue中,queue为null则放弃。

    另外,WeakHashMap中,map中有一个数组Entry[],其Entry继承了WeakReference,即弱引用。可以看到key绑定到了成员变量ReferenceQueue中,即key满足弱引用的特性,当key引用不存在时可被GC回收,但value内存并不会回收,而是等put、size()、clear()等方法触发expungeStaleEntries()清除无效的Entry(根据成员变量ReferenceQueue,遍历找到对应的Entry并置null)。

    看到这里,就明白了,WeakHashMap的实现是通过ReferenceQueue监听器对应key的可达性,进而实现自动删除那些引用不可达的key的,当key对象的引用可达发生变化时放入queue。

    private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> { V value; final int hash; Entry<K,V> next; /** * Creates new entry. */ 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; }

    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; } } } }

    待续。。。

    资料:http://hongjiang.info/java-referencequeue/

    转载请注明原文地址: https://ju.6miu.com/read-15734.html

    最新回复(0)