编程语言
首页 > 编程语言> > java – 弱参考可维护性

java – 弱参考可维护性

作者:互联网

我正在阅读java中的弱引用,听起来很简单,如果一个对象只有弱引用,那么它可以被垃圾收集器收集.除非您的参考在使用该值之前变为死亡,否则会发生什么?

例:

假设我有一个带有密钥{1,2,3,4,5}的弱哈希映射,所有值都是1.现在假设你有[1:10]中的数字的随机数生成器.现在每次获得该数字时,它都会检查它是否是地图中的一个键,然后给出一个临时的强引用.因此,使用此设置,您将拥有一些具有强引用的键,从而保留在内存中,但您也有可能在选择之前某些键将变为死亡.

如果我对弱哈希映射的直觉是正确的,那是否意味着地图在某些时候会从其原始状态改变?

解决方法:

尝试使用Integer对象作为WeakHashMap的键可能会导致一些奇怪的行为.首先,javadoc for WeakHashMap有以下注释:

This class is intended primarily for use with key objects whose equals methods test for object identity using the == operator. Once such a key is discarded it can never be recreated, so it is impossible to do a lookup of that key in a WeakHashMap at some later time and be surprised that its entry has been removed. This class will work perfectly well with key objects whose equals methods are not based upon object identity, such as String instances. With such recreatable key objects, however, the automatic removal of WeakHashMap entries whose keys have been discarded may prove to be confusing.

请考虑以下代码:

    WeakHashMap<Integer, String> map = new WeakHashMap<>();
    Integer k = Integer.valueOf(9001);
    map.put(k, "OVER 9000!?");

    while (true)
    {
        System.out.println(map.get(k));
        Thread.sleep(100);
        k = Integer.valueOf(9001);
        System.gc();
    }

循环将通过打印“OVER 9000!?”开始,但在第一个循环之后,原始密钥已被丢弃(即使现在存在对等于它的键的引用).因此,如果该密钥对象被垃圾收集,则该条目将从映射中删除,并且循环将开始打印“null”.因为我们称之为System.gc();丢弃密钥后,很可能在单个循环后发生这种情况.

但是,这并不是将Integer用作WeakHashMap键的问题的结束.如果将上面的值9001更改为1,您会发现行为发生了变化! (可能?这可能与实现有关.)现在,该条目永远不会从地图中删除.这是因为integer cache – Integer.valueOf(1)总是返回相同的Integer实例,但Integer.valueOf(9001)每次都会创建一个新的Integer实例.

第二个问题特定于Integer,但第一个问题实际上适用于您尝试使用其中equals不基于==的键的任何方案.如果equals基于==,那么你的问题并不真正适用 – 如果你不再对该键有强烈的引用,那么这个值是否会从地图中删除并不重要因为你不再有办法达到它 – 你不能重新创建一个使用基于身份的平等的密钥.

标签:java,weak-references,weakhashmap
来源: https://codeday.me/bug/20190828/1746515.html