Reputation: 925
I have cache, implemented with WeakHashMap, like this:
private static WeakHashMap<Object, WeakReference<Object>> objects = new WeakHashMap<>();
I have an instance of class City:
City c = new City();
I now add this instance to my map like this:
objects.put(c, new WeakReference<Object>(c));
According to WeakHashMap jvm implementation, if key doesn't have strong references to it, it's deleted from the map (in its free time).
So, if my object 'c' is not used in the program anymore, it will be deleted from 'objects' map.
So far, so good.
But what happens if I have two maps?
private static WeakHashMap<Object, WeakReference<Object>> objects1 = new WeakHashMap<>();
private static WeakHashMap<Object, WeakReference<Object>> objects2 = new WeakHashMap<>();
City c = new City();
objects1.put(c, new WeakReference<Object>(c));
objects2.put(c, new WeakReference<Object>(c));
Will GC collect the object 'c' in this case?
Upvotes: 3
Views: 118
Reputation: 326
For Sure it will collect it(when GC starts), because its still referenced by WeakReference and not a Strong reference, not matter how many WeakReferences are referencing it.
You can read about WeakReference here : WeakReference
Here is an Example to demonstrate it:
public class WeakHashMapExample {
//strongly reference key to prevent GC from collecting it
private static final Key stronglyRefKey1 = new Key(1);
public static void main(String[] args) throws InterruptedException {
WeakHashMap<Key, String> cache1 = new WeakHashMap<>();
WeakHashMap<Key, String> cache2 = new WeakHashMap<>();
//adding same keys
Key key2 = new Key(2);
cache1.put(stronglyRefKey1, "val 1");
cache1.put(key2, "val 2");
cache2.put(stronglyRefKey1, "val 1");
cache2.put(key2, "val 2");
key2 = null; // remove strong reference
//may or may not print Key(2) key, depends if GC starts at this point
System.out.println("cache1 = " + cache1);
System.out.println("cache2 = " + cache2);
//for GC to start so all weak reference should be cleared
System.gc();
//after GC ha been ran, key(2) will be removed because its only referenced by weak reference of the WeakHashMap
System.out.println("cache1 = " + cache1);
System.out.println("cache2 = " + cache2);
}
private static class Key{
int value;
private Key(int value) {
this.value = value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Key key = (Key) o;
if (value != key.value) return false;
return true;
}
@Override
public int hashCode() {
return value;
}
@Override
public String toString() {
return "Key{value=" + value +'}';
}
}
}
Upvotes: 1
Reputation: 974
Weak is weak, it won't become strong if it is joined by another weak.
It will be garbage collected if no other strong reference. No doubt.
Upvotes: 0
Reputation: 43052
Take a piece of paper, draw a graph with the objects as vertices, references as edges.
If you can't find a path of strong edges from a GC root (e.g. static field or local variable on the stack) to the object in equestion then it is not strongly reachable and thus eligible for GC.
Upvotes: 3