WeakHashMap vs HashMap

在下面的代码示例中,当键设置为null并且调用System.gc()WeakHashMap丢失所有映射并清空。

 class WeakHashMapExample { public static void main(String[] args) { Key k1 = new Key("Hello"); Key k2 = new Key("World"); Key k3 = new Key("Java"); Key k4 = new Key("Programming"); Map wm = new WeakHashMap(); wm.put(k1, "Hello"); wm.put(k2, "World"); wm.put(k3, "Java"); wm.put(k4, "Programming"); k1=null; k2=null; k3=null; k4=null; System.gc(); System.out.println("Weak Hash Map :"+wm.toString()); } } class Key{ private String key; public Key(String key) { this.key=key; } @Override public boolean equals(Object obj) { return this.key.equals((String)obj); } @Override public int hashCode() { return key.hashCode(); } @Override public String toString() { return key; } } 

Output: Weak Hash Map :{}

WeakHashMapHashMap一起使用并且键设置为null时, WeakHashMap不会丢失其键值映射。

 class WeakHashMapExample { public static void main(String[] args) { Key k1 = new Key("Hello"); Key k2 = new Key("World"); Key k3 = new Key("Java"); Key k4 = new Key("Programming"); Map wm = new WeakHashMap(); Map hm=new HashMap(); wm.put(k1, "Hello"); wm.put(k2, "World"); wm.put(k3, "Java"); wm.put(k4, "Programming"); hm.put(k1, "Hello"); hm.put(k2, "World"); hm.put(k3, "Java"); hm.put(k4, "Programming"); k1=null; k2=null; k3=null; k4=null; System.gc(); System.out.println("Weak Hash Map :"+wm.toString()); System.out.println("Hash Map :"+hm.toString()); } } class Key{ private String key; public Key(String key) { this.key=key; } @Override public boolean equals(Object obj) { return this.key.equals((String)obj); } @Override public int hashCode() { return key.hashCode(); } @Override public String toString() { return key; } } 

输出: Weak Hash Map :{Java=Java, Hello=Hello, World=World, Programming=Programming} Hash Map :{Programming=Programming, World=World, Java=Java, Hello=Hello}

我的问题是为什么即使在丢弃密钥之后, WeakHashMap也不会在第二个代码示例中丢失其条目?

当密钥不再可从实时代码中强烈访问时, WeakHashMap会丢弃条目。 由于HashMap维护对密钥的硬引用,因此密钥仍可访问,而WeakHashMap不会丢弃条目。

关键是行为与对关键对象的引用有关,而不是与曾经可能具有对键的引用的任何变量的值有关。

您已在指针k1,k2,k3,k4上设置null k1,k2,k3,k4HashMapWeakHashMap仍包含对这些Keys引用。 因为HashMap包含引用,GC的实际实例不会被GC删除。 WeakHashMap仍然打印所有这些。

尝试仅使用HashMap运行此示例 – >即使您已经清除了那些参考, HashMap仍将保留它们。

必须在其他地方丢弃对象 ,然后WeakHashMap清除该对象。 像WeakReference一样,它的目的是记住一个对象,如果它仍在使用中。 不会造成内存泄漏永远持有一个对象。

在你的例子中设置hm = null; 看看WeakHashMap清理的神奇之处。

HashMap支配gc(垃圾收集器)。

gc支配WeakHashMap。

即使我们在k1,k2,k3,k4 gc上设置null也不会从HashMap中删除,因为gc将它们全部删除并为WeakHashMap提供空映射,因此名称为WeakHashMap