I am understanding the concept of WeakhashMap. String literal and String object made it difficult to understand.
Following is the code:
package com.lnt.StringBuf;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
public class Test1 {
public static void main(String[] args) {
Map w = new WeakHashMap();
Map h = new HashMap<>();
String hkey = new String("hashkey");
String wkey = new String("weakkey");
/* String hkey = "hashkey";
String wkey = "weakkey";*/
h.put(hkey, 1);
w.put(wkey, 1);
System.gc();
System.out.println("Before");
System.out.println("hashmap size: " + h.size());
System.out.println("weakmap size: " + w.size());
System.out.println("Hashmap value: " + h.get("hashkey") + "\t"
+ "weakmap value: " + w.get("weakkey"));
hkey = null;
wkey = null;
System.gc();
System.out.println(hkey+" "+wkey);
System.out.println("After");
System.out.println("hashmap size: " + h.size());
System.out.println("weakmap size: " + w.size());
System.out.println("Hashmap value: " + h.get("hashkey") + "\t"
+ "weakmap value: " + w.get("weakkey"));
System.out.println(h.entrySet());
System.out.println(w.entrySet());
}
}
Output is:
Before
hashmap size: 1
weakmap size: 1
Hashmap value: 1 weakmap value: 1
null null
After
hashmap size: 1
weakmap size: 0
Hashmap value: 1 weakmap value: null
[hashkey=1]
[]
But when String hkey = new String("hashkey"); String wkey = new String("weakkey");
is replaced with following code, output changes.
String hkey = "hashkey";
String wkey = "weakkey";
Output is:
Before
hashmap size: 1
weakmap size: 1
Hashmap value: 1 weakmap value: 1
null null
After
hashmap size: 1
weakmap size: 1
Hashmap value: 1 weakmap value: 1
[hashkey=1]
[weakkey=1]
Question: Making String literal and String object 'null' impacts in different way in WeakHashMap. What is the reason?
First, you can't make an object
null
. You can make a variable referencenull
or reference an object, but making an objectnull
is not a concept that exists.The javadoc of
WeakHashMap
statesAt runtime, the JVM creates an
String
object for everyString
literal it sees while loading classes. These objects cannot be GC'ed until theClassLoader
that loaded them is GC'ed, regardless of them being referenced in aWeakHashMap
.This would be similar to doing
Since you have a reachable reference to the object somewhere else, it cannot be GC'ed, even if used in a weak collection.
Also note that
System.gc()
does not guarantee that Garbage Collection will run. Be mindful of that when using it as to not misinterpret results.