Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WeakHashMap doesn't remove obsolete entries

Tags:

java

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.

like image 953
maks Avatar asked Jan 15 '12 20:01

maks


People also ask

What is true about a 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.

When should we use WeakHashMap?

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.

What is weak hash Map in Java?

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.


2 Answers

Your keys are never garbage collected because Integers from -128 to 127 are cached (assuming Integer.valueOf is used, which it is for autoboxed ints). You could use values outside that range or use Integer st1 = new Integer(5) to ensure you aren't using cached objects.

like image 128
ColinD Avatar answered Oct 04 '22 14:10

ColinD


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();

...
like image 33
Russell Zahniser Avatar answered Oct 04 '22 14:10

Russell Zahniser