2

Recently, I try to figure out how WeakHashMap works. As code shows, map.isEmpty() will return true after System.gc() and size is strong referenced, so who change size?

    WeakHashMap<UniqueKey, BigImage> map = new WeakHashMap<>();

    UniqueKey key = new UniqueKey("abc");
    map.put(key, new BigImage());
    BigImage value = map.get(key);
    assertNotNull(value);

    key = null;
    System.gc();

    Thread.sleep(1000);
    assertTrue(map.isEmpty());
Pawan Tiwari
  • 518
  • 6
  • 26
liaoming
  • 153
  • 3
  • 10
  • 1
    It's the WeakHashMap itself: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/WeakHashMap.java#l363 – JB Nizet Oct 05 '18 at 10:26

2 Answers2

3

Look at the implementation internally:

public int size() {
    if (size == 0)
        return 0;
    expungeStaleEntries();
    return size;
}

specifically for expungeStaleEntries method that uses :

/**
 * Reference queue for cleared WeakEntries
 */
private final ReferenceQueue<Object> queue = new ReferenceQueue<>();

This method also updates size, before it is returned to you.

Eugene
  • 117,005
  • 15
  • 201
  • 306
1

The stale entries are removed when you call the size() method.

The size() method internally calls the private method expungeStaleEntries() in order to remove the stale entries (of course, if it is not already empty).

notionquest
  • 37,595
  • 6
  • 111
  • 105