WeakHashMap中只有key才是WeakReference,可以被gc自动回收,但是Value是强引用,需要调用get/put方法才会触发回收
- 如果构造函数中指定了ReferenceQueue,那么事后程序员可以通过该队列清理引用
- 如果构造函数中没有指定了ReferenceQueue,那么 GC 会自动清理引用
- 当弱引用指向的对象只能通过弱引用(没有强引用或弱引用)访问时,GC会清理掉该对象,之后,引用对象会被放到ReferenceQueue中
参考:Java WeakHashMap源码解析 写的很详细
public class WeakReference<T> extends Reference<T> {
public WeakReference(T r) { super(r, null); }
public WeakReference(T r, ReferenceQueue<? super T> q) { super(r, q); } }
|
Entry对象是个引用对象
public class WeakHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V> { private final ReferenceQueue<K> referenceQueue; private static final class Entry<K, V> extends WeakReference<K> implements Map.Entry<K, V> { Entry(K key, V object, ReferenceQueue<K> queue) { super(key, queue); } } }
|
public V put(K key, V value) { poll(); int index = 0; Entry<K, V> entry; if (entry == null) { modCount++; if (++elementCount > threshold) { rehash(); index = key == null ? 0 : (Collections.secondaryHash(key) & 0x7FFFFFFF) % elementData.length; } entry = new Entry<K, V>(key, value, referenceQueue); entry.next = elementData[index]; elementData[index] = entry; return null; } V result = entry.value; entry.value = value; return result; }
|
删除referenceQueue中的无效的Entry,释放内存空间
void poll() { Entry<K, V> toRemove; while ((toRemove = (Entry<K, V>) referenceQueue.poll()) != null) { removeEntry(toRemove); } }
|