WeakHashMap example
Asked Answered
B

6

23

I create a WeakHashMap as

WeakHashMap<Employee,String> map = new WeakHashMap<Employee,String>();
map.put(emp,"hello");

where emp is an Employee object. Now if I do emp = null or say emp object is no longer referenced, then will the entry be removed from the WeakHashMap i.e. will the size of Map be zero?
And will it be vice-versa in case of HashMap?
Is my understanding of WeakHashMap correct?

Borak answered 15/5, 2012 at 11:25 Comment(0)
B
15

I ran the sample code to understand the difference between HashMap and WeakHashMap

            Map hashMap= new HashMap();
            Map weakHashMap = new WeakHashMap();

            String keyHashMap = new String("keyHashMap");
            String keyWeakHashMap = new String("keyWeakHashMap");

            hashMap.put(keyHashMap, "helloHash");
            weakHashMap.put(keyWeakHashMap, "helloWeakHash");
            System.out.println("Before: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap"));

            keyHashMap = null;
            keyWeakHashMap = null;

            System.gc();  

            System.out.println("After: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap"));

The output will be:

Before: hash map value:helloHash and weak hash map value:helloWeakHash
After: hash map value:helloHash and weak hash map value:null
Borak answered 29/6, 2013 at 13:6 Comment(0)
P
42

A very simple example, to enlighten what has already been said :

import java.util.WeakHashMap;

public class WeakHashMapDemo {

    public static void main(String[] args) {
        // -- Fill a weak hash map with one entry
        WeakHashMap<Data, String> map = new WeakHashMap<Data, String>();
        Data someDataObject = new Data("foo");
        map.put(someDataObject, someDataObject.value);
        System.out.println("map contains someDataObject ? " + map.containsKey(someDataObject));

        // -- now make someDataObject elligible for garbage collection...
        someDataObject = null;

        for (int i = 0; i < 10000; i++) {
            if (map.size() != 0) {
                System.out.println("At iteration " + i + " the map still holds the reference on someDataObject");
            } else {
                System.out.println("somDataObject has finally been garbage collected at iteration " + i + ", hence the map is now empty");
                break;
            }
        }
    }

    static class Data {
        String value;
        Data(String value) {
            this.value = value;
        }
    }
}

Output :

    map contains someDataObject ? true
    ...
    At iteration 6216 the map still holds the reference on someDataObject
    At iteration 6217 the map still holds the reference on someDataObject
    At iteration 6218 the map still holds the reference on someDataObject
    somDataObject has finally been garbage collected at iteration 6219, hence the map is now empty
Premium answered 15/5, 2012 at 11:58 Comment(2)
For me it took much longer! Had to change the program :) "somDataObject has finally been garbage collected at iteration 708693, hence the map is now empty"Detestation
@Premium I had a tough time wondering what would happen to the weak reference in the map when the actual reference is GCed. Your example made it extremely clear that the weak ref would be itself removed from the map. Thanks a ton.Fiorin
B
15

I ran the sample code to understand the difference between HashMap and WeakHashMap

            Map hashMap= new HashMap();
            Map weakHashMap = new WeakHashMap();

            String keyHashMap = new String("keyHashMap");
            String keyWeakHashMap = new String("keyWeakHashMap");

            hashMap.put(keyHashMap, "helloHash");
            weakHashMap.put(keyWeakHashMap, "helloWeakHash");
            System.out.println("Before: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap"));

            keyHashMap = null;
            keyWeakHashMap = null;

            System.gc();  

            System.out.println("After: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap"));

The output will be:

Before: hash map value:helloHash and weak hash map value:helloWeakHash
After: hash map value:helloHash and weak hash map value:null
Borak answered 29/6, 2013 at 13:6 Comment(0)
V
6

*will the entry be removed from the WeakHashMap i.e. will the size of Map be zero? *

If emp contained the last reference making the Employee strongly reachable then the entry in the map may be removed.

The Java docs sums it up pretty well:

A hashtable-based Map implementation 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 [...]. 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 will it be vice-versa in case of HashMap?

Removing the entry from the WeakHashMap will not affect any other references in the program.

Veto answered 15/5, 2012 at 11:28 Comment(3)
Yep, a WeakHashMap contains weak references to the objects. A weak reference has it's pointer "zapped" if the garbage collector discovers that it (and other weak references) is the last remaining reference to the object. But this only happens on certain GC cycles. Offhand, I don't know what happens to the map's count when this occurs.Pisolite
@Veto "If emp contained the last reference making the Employee strongly reachable then the entry in the map may be removed." I didn't get it. Can you please elaborate more?Borak
@anand, If emp was the only variable that referred to some Employee (apart from other weak references such as the one in the hash map), then doing emp = null will make the employee in question eligible for garbage collection. Read up on reachability.Veto
F
2

WeakHashMap example:

Map map = new WeakHashMap();
Foo foo =  new Foo();
map.put(foo, "bar");
foo=null; // strong refrence is removed and object is available for garbage collection.  

HashMap example:

Map map = new HashMap();
Foo foo =  new Foo();
map.put(foo, "bar");
foo=null; // even though the reference is nullified object will not garbage collected because map is having Strong refrence.
Foldboat answered 16/12, 2017 at 11:33 Comment(0)
F
1

Reference in java are memory address where the created objects points in the memory. In a WeakHashMap, concept of Weak Reference is used.

As soon as you create an object in java and assign it to some variable, it becomes strongly reachable.

Weak reference object can somewhat be similar to object that has no memory references i.e. it can be garbage collected now.

Fjeld answered 8/1, 2015 at 15:1 Comment(0)
S
1

In other Map implementations like a HashMap, the keys are strongly reachable. For example, if a HashMap has keys as Person class as shown below and if Person object is set to null, even after this if we will do map.get(Person) we will get the value from the memory since the keys are strongly referenced in a HashMap.

wm.put(person, person.getFirstName());
person = null;
System.gc();
System.out.println("Hash Map :" + wm.toString());

Output : Hash Map :{test.Person@12dacd1=John}

Compared to HashMap, WeakHashMap is the one which will remove its enteries as soon as the keys have no reference in the memory. For example, if a WeakHashMap has keys as Person class as shown below and if Person object is set to null, now if you do map.get(Person) we will get null out of it because the key has no reference (or rather weakly reachable).

wm.put(person, person.getFirstName());
person = null;
System.gc();
System.out.println("Weak Hash Map :" + wm.toString());

Output : Weak Hash Map :{}

Shore answered 13/1, 2015 at 14:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.