猿问

HashMap 与 WeakHashMap 一起被垃圾收集?

据我所知,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 Executed

hashmap:: Finalize Method Executed

null

null

仅使用 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}


犯罪嫌疑人X
浏览 189回答 3
3回答

LEATH

首先不要使用finalize- 它已被弃用,有更好的方法来清理你自己,所以到处都是这样的帖子(ReferenceQueue并且SoftReferences是这样的帖子)。然后不要使用内部缓存的对象作为WeakHashMap(String就是这样的) 中的键。最后一点是,这与 无关WeakHashMap,这是对象的基本活力。在您的第一个示例中,您明确地将引用设置为null,因此它们会被 GC 清除,在您的第二个示例中您没有,并通过System.out.println(hashMap);;保持对它的强引用;因此它不会被收集。

慕盖茨4494581

在您的第一个示例中,您将hashMap变量设置为null.&nbsp;这样就不再有对 HashMap 对象的引用,它可以像任何其他类型的对象一样被垃圾收集。HashMap并且WeakHashMap在这方面没有什么不同。不同之处在于 a 中的键在WeakHashMap没有外部引用时可能会被垃圾收集。在正常情况下HashMap,这不会发生,因为映射本身包含对键的引用。一旦收集到密钥,就WeakHashMap可以清除整个相应的条目。这个答案更详细地介绍了它。

慕姐4208626

我认为您误解了 GC 的工作原理。一句话:类的实例在不再被引用时被垃圾回收。它与类型无关。这就是为什么要注意变量的范围如此重要。如果您保留对不再需要的对象的引用,它将不会被收集并且您将浪费资源。此外,您正在调用 System.gc()...您不能以编程方式调用 GC。它会按照自己的规则运行。充其量,您可以“建议”您希望 GC 运行的 JVM。我建议你看看:https&nbsp;:&nbsp;//www.dynatrace.com/resources/ebooks/javabook/how-garbage-collection-works/
随时随地看视频慕课网APP

相关分类

Java
我要回答