Java HashMap与WeakHashMap一起被垃圾收集?
据我所知,HashMap不应该被垃圾收集,WeakHashMap应该被垃圾收集,但是当我运行这段代码时,HashMap和WeakHashMap都被垃圾收集。Java HashMap与WeakHashMap一起被垃圾收集?,java,collections,hashmap,garbage-collection,weakhashmap,Java,Collections,Hashmap,Garbage Collection,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> hash
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;
}
}
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;
}
}
仅使用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"));
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;
}
}
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;
}
}
我想你误解了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"));
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;
}
}
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;
}
}
这就是为什么关注变量的范围是如此重要。如果保留对不再需要的对象的引用,则不会收集该对象,并且会浪费资源
另外,您正在调用System.gc()。。。您不能以编程方式调用GC。它将按照自己的规则运行。充其量,您可以“建议”希望GC运行的JVM
我建议你看一看:首先不要使用
finalize
-它已经被弃用了,有更好的方法可以自己清理,因此到处都是这样的帖子(ReferenceQueue
和SoftReferences
就是其中之一)
然后不要使用内部缓存的对象作为WeakHashMap
中的键(String
就是这样)
最后一点是,这与
WeakHashMap
无关,这是对象的基本活力。在第一个示例中,您显式地将引用设置为null
,因此GC会清除它们,而在第二个示例中,您不会清除它们,并通过System.out.println(hashMap)保留对它的强引用代码>;因此,它不会被收集 在第一个示例中,将hashMap
变量设置为null
。这样就不再引用HashMap对象,它可以像任何其他类型的对象一样被垃圾收集HashMap
和WeakHashMap
在这方面没有区别
不同之处在于,WeakHashMap
中的密钥在没有外部引用时可能会被垃圾收集。在普通的HashMap
中,这不会发生,因为映射本身包含对键的引用
收集钥匙后,WeakHashMap
可能会清除整个相应条目。详细介绍它。在第行hashMap=null代码>取消引用HashMap的对象。在任何情况下,在设置null后,在垃圾收集的下一个周期,它将由垃圾收集器收集
在第二种情况下,您没有将hashMap设置为null
两者的区别是:
WeakHashMap是Map接口的一个实现。WeakHashMap与HashMap几乎相同,但WeakHashMap的情况除外,如果将对象指定为不包含任何引用的键,则该对象可以进行垃圾收集,即使它与WeakHashMap关联。i、 垃圾收集器支配着WeakHashMap。您在这里遇到了很多问题,使用被弃用的finalize
(出于某种原因!)和使用String
作为WeakHashMap
的键,这又是另一个让人大吃一惊的地方。我真的不明白您想证明什么,在第二个示例中,您通过System.out.println(hashMap)强烈引用了非null的hashMap
代码>-所以垃圾收集器绝对不能回收它;不像你的第一次example@Eugene好的,谢谢你的指点,但是在WeakHashMap中使用字符串不能对HashMap被垃圾收集负责。对吗?因为你把它设为null,明确地添加了一个答案来捕获这些评论。我认为您还应该解释在收集密钥后如何从WeakHashMap
中清除条目…@Eugene这有点复杂,取决于实现,但我现在链接了另一个答案。