WeakHashMap的工作原理

概述

WeakHashMap 类似HashMap ,不同点在WeakHashMap的key是弱引用的key。

谈到弱引用,在这里回顾下四种引用吧

  • 强引用:Object obj=new Object()这种,只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。
  • 软引用: 一般情况不会回收,如果内存不够要溢出时才会进行回收
  • 弱引用:当垃圾收集器开始工作,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
  • 虚引用:为一个对象设置虚引用的唯一目的只是为了能在这个对象被回收时收到一个系统的通知。

正是因为WeakHashMap使用的是弱引用,它的对象可能随时被回收。WeakHashMap 类的行为部分取决于垃圾回收器的动作,调用两次size()方法返回不同值,调用两次isEmpty(),一次返回true,一次返回false都是可能的

WeakHashMap工作原理

WeakHashMap具有弱引用的特点:随时被回收对象。

发生GC时,WeakHashMap是如何将Entry移除的呢?

WeakHashMap内部的Entry继承了WeakReference,即弱引用,所以就具有了弱引用的特点,随时可能被回收。看下源码:

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;
        }
        ......
WeakHashMap是如何将Entry移除的?

GC每次清理掉一个对象之后,引用对象会放到ReferenceQueue的,接着遍历queue进行删除。WeakHashMap的增删改查操作,就是直接/间接调用expungeStaleEntries()方法,达到及时清除过期entry的目的。可以看下expungeStaleEntries源码

/**
     * Expunges stale entries from the table.
     */
    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;
                }
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值