【发布时间】:2016-01-19 13:32:23
【问题描述】:
WeakHashMap 中的关键对象变得弱可达。并且 map 应该在 GC 之后删除条目。但是对值对象的强引用仍然存在。为什么?
使用 guava 弱键映射观察到相同的行为。
预期输出:
...
refKey.get = null
refValue.get = null
但我得到了输出:
map.keys = []
map.values = []
map.size = 0
refKey.get = null
refValue.get = (123)
代码:
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;
import com.google.common.collect.MapMaker;
public class Test {
static class Number {
final int number;
public Number(int number) { this.number = number; }
public String toString() { return "(" + number + ")"; }
}
static class Key extends Number {
public Key(int number) { super(number); }
}
static class Value extends Number {
public Value(int number) { super(number); }
}
public static void main(String args[]) {
//Map<Key, Value> map = new MapMaker().weakKeys().makeMap();
Map<Key, Value> map = new WeakHashMap<>();
Key key = new Key(1);
Value value = new Value(123);
map.put(key, value);
WeakReference<Key> refKey = new WeakReference<>(key);
WeakReference<Value> refValue = new WeakReference<>(value);
key = null;
value = null;
System.gc();
System.out.println("map.keys = " + map.keySet());
System.out.println("map.values = " + map.values());
System.out.println("map.size = " + map.size());
System.out.println("refKey.get = " + refKey.get());
System.out.println("refValue.get = " + refValue.get());
}
}
UPD:
我尝试在 jСonsole 和 jcmd 中执行 GC,但输出没有改变。
【问题讨论】:
-
@Thilo 在这种情况下,我会得到输出:
refKey.get() = (1)。但是refKey.get() = null. -
但是当垃圾收集只完成一半时,你可以获得一个输出,不是吗?
-
您是否尝试使用 jconsole 或 jcmd 来查看是否会改变输出(您必须睡足够长的时间才能适应它)。
-
@Thilo 感谢您的建议。我尝试了 jConsole 和 jcmd,但输出没有改变。
-
@Thilo 尝试了一百个键和值。收集了所有键,但收集了所有值 - 没有。
标签: java garbage-collection guava weakhashmap