2

I hava a test application with one class that stores a map and a button that invokes method of that class:

Map<Object, Object> weakMap = new WeakHashMap<Object, Object>();

The button does this:

public void fillWeakHashMap(int size) {
    List<String> createObjects = (List<String>) createObject(size);
    for (Object ob : createObjects) {
        weakMap.put(ob, ob);
    }
}

So the main class with the map lives but objects which I put to it are created in separate method and since it is a WeakHashMap I thought that after exit from the method fillWeakHashMap the keys / objects in map would be cleared by the GC.

I opened the VisualVM->VisualGC and clicked Monitor->PerformGC 10 times and the Old space is almost full meaning that GC isnt clearing those objects. So what am I doing wrong?

RealSkeptic
  • 33,993
  • 7
  • 53
  • 79
  • 1
    Try using `weakMap.put(ob, "")` instead of `weakMap.put(ob,ob)`. – RealSkeptic May 02 '15 at 15:17
  • Thanks! I changed it to weakMap.put(ob, ""), I see now that GC works - some Old objects are removed but some object in Old space are left... Moreover I am also playing with permgen space and I am using a loop with 100k+ operations like new new XStream().fromXML(someXML) which increases pergen in loop but GC is clearing them. Does it mean that I won't be able to simulate PergenSpace exception? –  May 02 '15 at 16:07

2 Answers2

9

The first sentence of WeakHashMap's javadoc says:

Hash table based implementation of the Map interface, with weak keys. An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. More precisely, the presence of a mapping for a given key will not prevent the key from being discarded by the garbage collector, that is, made finalizable, finalized, and then reclaimed. When a key has been discarded its entry is effectively removed from the map, so this class behaves somewhat differently from other Map implementations.

and somewhat further down, it writes:

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.

That is, only the keys are weakly referenced, but the values are strongly referenced. In your code, each key is also used a value, therefore strongly referenced, and therefore not garbage collected.

meriton
  • 68,356
  • 14
  • 108
  • 175
  • Thanks! I changed it to weakMap.put(ob, ""), I see now that GC works - some Old objects are removed but some object in Old space are left... Moreover I am also playing with permgen space and I am using a loop with 100k+ operations like new new XStream().fromXML(someXML) which increases pergen in loop but GC is clearing them. Does it mean that I won't be able to simulate PergenSpace exception? –  May 02 '15 at 16:08
1

You are keeping a reference for each object in the map like ob is still referring itself that is why nothing is being cleared, since GC cant claimed that those objects are not is use and can be cleaned.

Hussein Zawawi
  • 2,907
  • 2
  • 26
  • 44