As of my understanding HashMap should not be garbage collected and WeakHashMap should be garbage collected but When I'm running this code both hashmap and weakhashmap are being garbage collected.
import java.util.HashMap;
import java.util.WeakHashMap;
public class WeakHashMapDemo {
public static void main(String[] args) {
HashMap<String,Temp> hashMap= new HashMap<>();
hashMap.put("a", new Temp("hashmap"));
WeakHashMap<String,Temp> weakHashMap= new WeakHashMap<>();
weakHashMap.put("a", new Temp("identity hashmap"));
hashMap= null;
weakHashMap= null;
System.gc();
try {
Thread.sleep(5000);
}catch(InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
System.out.println(hashMap);
System.out.println(weakHashMap);
}
}
class Temp {
String name;
Temp(String name) {
this.name= name;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println(name+":: Finalize Method Executed");
}
@Override
public String toString() {
return this.name;
}
}
Output:
identity hashmap:: Finalize Method Executed
hashmap:: Finalize Method Executed
null
null
While using only HashMap, it is not being garbage collected by the GC.
import java.util.HashMap;
import java.util.WeakHashMap;
public class WeakHashMapDemo {
public static void main(String[] args) {
HashMap<String,Temp> hashMap= new HashMap<>();
hashMap.put("a", new Temp("hashmap"));
System.gc();
try {
Thread.sleep(5000);
}catch(InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
System.out.println(hashMap);
}
}
class Temp {
String name;
Temp(String name) {
this.name= name;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println(name+":: Finalize Method Executed");
}
@Override
public String toString() {
return this.name;
}
}
Output:
{a=hashmap}
First of all do not use finalize
- it has been deprecated, there are better ways to clean after yourself and SO is full of such posts (ReferenceQueue
and SoftReferences
are among such).
Then don't use objects that are cached internally as keys in WeakHashMap
(String
is such).
Last point is that this has nothing to do with WeakHashMap
, this is basic liveliness of Objects. In your first example you explicitly set the reference to null
, thus they are cleared by GC, in your second one you don't, and keep a strong reference to it via System.out.println(hashMap);
; thus it will not get collected.