Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will a WeakHashMap's entry be collected if the value contains the only strong reference to the key?

I need to associate some data with a key for its lifetime, so I am using a WeakHashMap. However, in addition I need to get a key by its corresponding value. The easy way to do it is to hold on to the reference when creating a value:

public class Key {}

public class Value { 
    final public Key key;
    public Value(Key k) {
        key = k;
    }
}

Of course, while I use Value in my program, its key won't go away. However, if there are no more references to either key or its value outside the map, will it be garbage collected? Or does the surviving strong reference in the value prevent it?

like image 746
Alexey Romanov Avatar asked Nov 08 '11 14:11

Alexey Romanov


People also ask

What is true about WeakHashMap?

Simply put, the WeakHashMap is a hashtable-based implementation of the Map interface, with keys that are of a WeakReference type. An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use, meaning that there is no single Reference that point to that key.

How does WeakHashMap work?

Each key object in a WeakHashMap is stored indirectly as the referent of a weak reference. Therefore a key will automatically be removed only after the weak references to it, both inside and outside of the map, have been cleared by the garbage collector.


2 Answers

No it won't be garbage collected, see the Javadoc:

Implementation note: The value objects in a WeakHashMap are held by ordinary strong references. Thus care should be taken to ensure that value objects do not strongly refer to their own keys, either directly or indirectly, since that will prevent the keys from being discarded.

As mentioned by @biziclop one solution would be to store a weak reference to the key in your value object.

public class Value { 
  final public WeakReference<Key> key;
  public Value(Key k) {
    this.key = new WeakReference<Key>(k);
  }
}
like image 131
laguille Avatar answered Oct 13 '22 01:10

laguille


Looking at the implementation, the answer appears to be no.

This is from the WeakHashMap source:

/**
 * The table, resized as necessary. Length MUST Always be a power of two.
 */
private Entry[] table;

...

private static class Entry<K,V> extends WeakReference<K> implements Map.Entry<K,V> {
    private V value;
    ...
}

As you can see, Entry objects are referenced strongly by the map itself. So if the map is accessible, so will be the Entry, therefore your Value objects, and your key too.

like image 23
biziclop Avatar answered Oct 13 '22 00:10

biziclop