首先,我想澄清我对以下问题的理解,WeakReference
因为以下问题取决于相同的问题。
static void test() {
Person p = new Person();
WeakReference<Person> person = new WeakReference<>(p);
p = null;
System.gc();
System.out.println(person.get());
System.out.println(person);
}
static class Person {
String name;
}
static class PersonMetadata {
String someData;
public PersonMetadata(String met) {
someData = met;
}
}
上面代码的输出是
null
java.lang.ref.WeakReference@7852e922
这意味着,尽管一旦 GC 运行,实际的 person 对象就会被垃圾回收,但WeakReference<Person>
内存中存在一个类对象,此时它不指向任何东西。
现在考虑到上述理解是正确的,我对它的WeakHashMap<K,V>
工作原理感到困惑。在下面的代码中
public static void main(String[] args) {
Person p = new Person();
p.name = "John";
WeakHashMap<Person, PersonMetadata> map = new WeakHashMap<>();
PersonMetadata meta = new PersonMetadata("Geek");
map.put(p, meta);
p = null;
System.gc();
if (map.values().contains(meta)) {
System.out.println("Value present");
} else {
System.out.println("Value gone");
}
}
static class Person {
String name;
}
static class PersonMetadata {
String someData;
public PersonMetadata(String met) {
someData = met;
}
}
输出: Value gone
现在的问题是,据说 key inWeakHashMap<K,V>
是一个弱引用,这意味着在上面的代码中,当p
成为null
实际对象时可以被垃圾收集,因为没有更多对该对象的强引用,但是the 和作为类对象的值PersonMetadata
正在被垃圾收集,因为第一个代码证明WeakReference
即使收集了实际对象,类的对象也没有被垃圾收集。