1 /**
2 * Reference queue for cleared WeakEntries
3 */
4 // 所有Entry在构造时都传入该queue
5 private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
6 /**
7 * Expunges stale entries from the table.
8 */
9 private void expungeStaleEntries() {
10 for (Object x; (x = queue.poll()) != null; ) {
11 synchronized (queue) {
12 // e 为要清理的对象
13 @SuppressWarnings("unchecked")
14 Entry<K,V> e = (Entry<K,V>) x;
15 int i = indexFor(e.hash, table.length);
16 Entry<K,V> prev = table[i];
17 Entry<K,V> p = prev;
18 // while 循环遍历冲突链
19 while (p != null) {
20 Entry<K,V> next = p.next;
21 if (p == e) {
22 if (prev == e) //表示x是桶链表的第一个元素
23 table[i] = next;
24 else
25 prev.next = next; //跳过x元素
26 // Must not null out e.next;
27 // stale entries may be in use by a HashIterator
28 // 可以看到这里把value赋值为null,来帮助 GC 回收强引用的value
29 e.value = null; // Help GC
30 size--;
31 break;
32 }
33 prev = p;
34 p = next;
35 }
36 }
37 }
38 }