Reputation: 2201
There is a WeakHashMap instance initialized with, for example, 500 entries. Now, its keys have not been referenced anywhere in the running application for a day or so. Will this map's entries be removed automatically after a certain time gets passed?
My understanding is that if key is not referenced then corresponding entries will be removed from the map.
Upvotes: 3
Views: 2081
Reputation: 365
Well, first we narrow down the question.
QUESTION: We have a WeakHashMap
in which we have some entries. Will those entries will be garbage collected if the entries are not being used?
WeakHashMap<Object, Object> wkMap = new WeakHashMap<>()
Object obj1 = new Object();
Object obj2 = new Object();
Objcet obj1Meta = new Object();
Objcet obj2Meta = new Object();
wkMap.put(obj1, obj1Meta);
wkMap.put(obj2, obj2Meta);
First of all, it's not about being used, neither it has any relation with time: it's about whether the reference to the map (wkMap
in this case) is in scope; if not, then the entire map is eligible for garbage collection, that's quite straightforward. But if not, then...
One thing we need to check is whether the objects which are weakly referenced by the keys of the map are already garbage collected or not. In this case obj1
and obj2
.
If these objects have not been garbage collected, then their corresponding entries will be there in the map. Garbage collector is not going to reclaim. Again straightforward.
Now the tricky case: the objects referenced weakly by obj1
, obj2
have been garbage collected. There is no need of their metadata present in the map wkMap
. Ideally they should be garbage collected, and eventually they are. But the question is how...
obj1
, obj2
become eligible for garbage collectionwkMap
.ReferenceQueue
attached to it. If there is any then GC puts the weak reference to that ReferenceQueue
. GC is done.null
. Wait, then who does that? Let's see next:That manual clean-up is done by WeakHashMap
itself. Let us check the size()
code inside WeakHashMap
:
public int size() {
if (size == 0)
return 0;
expungeStaleEntries();
return size;
}
Concentrate on expungeStaleEntries()
; it is the one which removes all the entries from the map which are there in the ReferenceQueue
as well, and the entries become eligible for garbage collection (a single reference queue is attached to all the weak references used as a key in the map). Check expungeStaleEntries()
code as well.
Now in a nutshell, if from your code you call some method on the WeakHashMap
, which internally calls this expungeStaleEntries()
method, only then will the entries become eligible for garbage collection.
expungeStaleEntries()
size()
reSize()
isEmpty()
putAll()
Hope this makes things clear.
Upvotes: 4
Reputation: 49626
Will this map's entries be removed automatically after a certain time gets passed?
It depends on when the Garbage Collector comes. There is no guarantee that it reclaims "garbage" even once a day.
The behavior of the
WeakHashMap
class depends in part upon the actions of the garbage collector, so several familiar (though not required)Map
invariants do not hold for this class. Because the garbage collector may discard keys at any time, aWeakHashMap
may behave as though an unknown thread is silently removing entries.
Upvotes: 2
Reputation: 8841
In this code
WeakHashMap<Group,String> map = new WeakHashMap<>();
Group group1 = new Group();
Group group2 = new Group();
map.put(group1,"one");
map.put(group2,"two");
System.out.println(map);
group1 = null;
System.gc();
System.out.println(map);
In the first print statement , you will see that hashmap has two elements and in the second print statement it will have only one element. Because the reference to the first element is now null. So yes all keys whose references point to null will get removed the next time GC runs.
{Group@53e25b76=one, Group@73a8dfcc=two}//First print
{Group@73a8dfcc=two}//Second print
Upvotes: 0
Reputation: 18235
It will be removed when GC runs if your key is not referenced anywhere: (Reference)
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.
The removal time is unknown:
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.
But be careful, some object like boxed Integer of small integers like -127-> 127 are cached by JVM so if you use autoboxed Integer key, it will never be removed from the Map.
Upvotes: 3