How can I model the removal of entries in WeakHashMap if there are no active references to one of it keys. I have next code:
WeakHashMap<Integer, String> weakMap = new WeakHashMap<Integer, String>();
Integer st1 = 5;
Integer st2 = 6;
String val = "BB";
weakMap.put(st1, "AA");
weakMap.put(st2, val);
st1 = 10;
//st1 = null;
//System.gc();
for (Map.Entry<Integer, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
The output is always
6 BB
5 AA
But I expect to get only 6 BB
Even if I decomment commented lines it still produce the same output. As I understand if the key in WeakHashMap
has no active reference somewhere else outside this weakHashMap
the entry with the specified key has to be removed. Am I right? If no, please, suggest the right solution.
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.
You can use a WeakHashmap to reduce the chance of a memory leak as a result of caching some object. The WeakHashMap will automatically remove entries whenever all references to the key are removed.
WeakHashMap is an implementation of the Map interface. WeakHashMap is almost same as HashMap except in case of WeakHashMap, if object is specified as key doesn't contain any references- it is eligible for garbage collection even though it is associated with WeakHashMap. i.e Garbage Collector dominates over WeakHashMap.
Your keys are never garbage collected because Integer
s from -128 to 127 are cached (assuming Integer.valueOf
is used, which it is for autoboxed int
s). You could use values outside that range or use Integer st1 = new Integer(5)
to ensure you aren't using cached objects.
The Integer objects from -1000 to 1000 (or somewhere thereabouts) are interned. This means that autoboxing and valueOf()
return an object which is stored internally in Integer
and hence never garbage collected. You will see the intended behavior if you do this:
Integer st1 = new Integer(5);
Integer st2 = new Integer(6);
...
st1 = 10;
System.gc();
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With