为了账号安全,请及时绑定邮箱和手机立即绑定

HashMap 与 WeakHashMap 一起被垃圾收集?

HashMap 与 WeakHashMap 一起被垃圾收集?

犯罪嫌疑人X 2021-11-11 16:56:58
据我所知,HashMap 不应该被垃圾收集,WeakHashMap 应该被垃圾收集,但是当我运行这段代码时,hashmap 和 weakhashmap 都被垃圾收集。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;    }}输出:identity hashmap:: Finalize Method Executedhashmap:: Finalize Method Executednullnull仅使用 HashMap 时,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;    }}输出:{a=hashmap}
查看完整描述

3 回答

?
LEATH

TA贡献1936条经验 获得超6个赞

首先不要使用finalize- 它已被弃用,有更好的方法来清理你自己,所以到处都是这样的帖子(ReferenceQueue并且SoftReferences是这样的帖子)。

然后不要使用内部缓存的对象作为WeakHashMap(String就是这样的) 中的键。

最后一点是,这与 无关WeakHashMap,这是对象的基本活力。在您的第一个示例中,您明确地将引用设置为null,因此它们会被 GC 清除,在您的第二个示例中您没有,并通过System.out.println(hashMap);;保持对它的强引用;因此它不会被收集。



查看完整回答
反对 回复 2021-11-11
?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

在您的第一个示例中,您将hashMap变量设置为null. 这样就不再有对 HashMap 对象的引用,它可以像任何其他类型的对象一样被垃圾收集。HashMap并且WeakHashMap在这方面没有什么不同。

不同之处在于 a 中的WeakHashMap没有外部引用时可能会被垃圾收集。在正常情况下HashMap,这不会发生,因为映射本身包含对键的引用。

一旦收集到密钥,就WeakHashMap可以清除整个相应的条目。这个答案更详细地介绍了它。


查看完整回答
反对 回复 2021-11-11
?
慕姐4208626

TA贡献1852条经验 获得超7个赞

我认为您误解了 GC 的工作原理。

一句话:类的实例在不再被引用时被垃圾回收。它与类型无关。

这就是为什么要注意变量的范围如此重要。如果您保留对不再需要的对象的引用,它将不会被收集并且您将浪费资源。

此外,您正在调用 System.gc()...您不能以编程方式调用 GC。它会按照自己的规则运行。充其量,您可以“建议”您希望 GC 运行的 JVM。

我建议你看看:https : //www.dynatrace.com/resources/ebooks/javabook/how-garbage-collection-works/


查看完整回答
反对 回复 2021-11-11
  • 3 回答
  • 0 关注
  • 183 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信