据我理解,HashMap不应该被垃圾收集,WeakHashMap应该被垃圾收集,但是当我运行这段代码时,hashmap和弱hashmap都是垃圾收集的。
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}发布于 2018-10-11 12:43:13
首先,不要使用finalize --它已经被废弃了,有更好的方法在你自己之后进行清理,所以有很多这样的帖子(ReferenceQueue和SoftReferences就是其中之一)。
然后,不要使用内部缓存的对象作为WeakHashMap中的键(String就是这样)。
最后一点是,这与WeakHashMap无关,这是对象的基本活力。在您的第一个示例中,您显式地设置了对null的引用,因此它们被GC清除,在第二个例子中没有,并且通过System.out.println(hashMap);保持对它的强烈引用;因此它不会被收集。
发布于 2018-10-11 12:44:31
在第一个示例中,您将hashMap变量设置为null。这样就不再有对HashMap对象的引用了,它可以像任何其他类型的对象一样被垃圾收集。HashMap和WeakHashMap在这方面没有什么不同。
区别在于,当没有外部引用时,WeakHashMap中的键可能会被垃圾收集。在普通的HashMap中,这种情况不会发生,因为映射本身包含对键的引用。
一旦收集到密钥,WeakHashMap可能会清除整个相应的条目。this answer将更详细地介绍它。
发布于 2018-10-11 12:40:12
我想你误解了GC的工作原理。
在一句话中:类的实例在不再被引用时被垃圾收集。与.类型无关。
这就是为什么要注意变量的范围是如此重要。如果您保留了对您不再需要的对象的引用,它将不会被收集,您将浪费资源。
另外,您正在调用System.gc()..。您不能以编程方式调用GC。它将按照自己的规则运行。充其量,您可以“建议”希望GC运行的JVM。
我建议你看看:https://www.dynatrace.com/resources/ebooks/javabook/how-garbage-collection-works/
https://stackoverflow.com/questions/52760002
复制相似问题