【问题标题】:Will a WeakHashMap's entry be collected if the value contains the only strong reference to the key?如果值包含对键的唯一强引用,是否会收集 WeakHashMap 的条目?
【发布时间】:2011-11-08 14:28:01
【问题描述】:

我需要将一些数据与其生命周期内的密钥相关联,因此我使用WeakHashMap。但是,除此之外,我还需要通过其对应的值获取一个键。最简单的方法是在创建值时保持引用:

public class Key {}

public class Value { 
    final public Key key;
    public Value(Key k) {
        key = k;
    }
}

当然,当我在我的程序中使用Value 时,它的key 不会消失。但是,如果在映射之外没有更多对键或其值的引用,它会被垃圾回收吗?还是值中幸存的强引用阻止了它?

【问题讨论】:

    标签: java weak-references weakhashmap


    【解决方案1】:

    不,它不会被垃圾回收,请参阅Javadoc

    实现说明:WeakHashMap 中的值对象由普通的强引用持有。因此,应注意确保值对象不会直接或间接地强烈引用自己的键,因为这会防止键被丢弃。

    正如@biziclop 所提到的,一种解决方案是在值对象中存储对键的弱引用。

    public class Value { 
      final public WeakReference<Key> key;
      public Value(Key k) {
        this.key = new WeakReference<Key>(k);
      }
    }
    

    【讨论】:

    • @biziclop 同样来自 Javadoc:处理这个问题的一种方法是在插入之前将值本身包装在 WeakReferences 中,如:m.put(key, new WeakReference(value)),然后展开每次得到。这应该可以解决问题!
    • 要么在值对象中存储对键的弱引用,要么只存储对键的弱引用。因为如果您将值包装在 WR 中,您最终可能会得到一个已经收集到值的现有键。
    【解决方案2】:

    查看实现,答案似乎是否定的。

    这是来自WeakHashMap 来源:

    /**
     * The table, resized as necessary. Length MUST Always be a power of two.
     */
    private Entry[] table;
    
    ...
    
    private static class Entry<K,V> extends WeakReference<K> implements Map.Entry<K,V> {
        private V value;
        ...
    }
    

    如您所见,Entry 对象被地图本身强烈引用。因此,如果地图是可访问的,那么EntryValue 对象和您的密钥也是如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-13
      • 2012-02-28
      • 1970-01-01
      • 2020-02-19
      • 1970-01-01
      • 1970-01-01
      • 2018-09-12
      • 2021-12-10
      相关资源
      最近更新 更多