WeakHashMap的用法?

M S*_*ach 6 java hashmap weakhashmap

WeakHashMap是Map接口的一个实现,如果相应的键不再被任何程序部分引用,Grabage Collector可以回收值对象的内存.因此,如果密钥不再用于程序中.它的Entry对象将被垃圾收集,无论其用途如何.它清晰到这里

这与HashMap不同,即使不再引用key,值对象仍保留在HashMap中.我们需要在HashMap对象上显式调用remove()方法来删除值.调用remove将只删除map中的条目.它对GC的准备将取决于它是否仍然在程序中的某个地方使用.

请找到上面解释的编码示例

根据我的理解,在HashMap上使用WeakHashMap

我的理解是,只有当我们想要确保Grabage Collector在任何部分程序不再引用密钥时回收值对象时,我们才应该使用WeakHashMap.这使程序内存有效我的理解是正确的吗?

根据JavaDocs使用WeakHashMap ,我可以发现这个声明

此类主要用于密钥对象,其等于方法使用==运算符测试对象标识.

我没有得到上述声明的含义以及它与我对WeakHashMap用法的理解形成对比.实际上我没有得到这个陈述与WeakHashMap的使用有何关系?

更新: - 进一步仔细阅读下面的声明javadocs

当其密钥不再正常使用时,WeakHashMap中的条目将自动被删除.更准确地说,给定密钥的映射的存在不会阻止密钥被垃圾收集器丢弃,即,可以最终化,最终化,然后回收.当一个键被丢弃时,它的条目将被有效地从地图中删除,因此该类的行为与其他Map实现略有不同.

为了我和他人的利益,我正在修改我的理解

根据我的修订理解,在HashMap上使用WeakHashMap

我们应该只在我们想要确保在GC运行时从地图中删除键值对时才能使用WeakHashMap,而键不再是普通用途而不是map本身.

例如: -

    WeakHashMap<Integer, String> numbers = new WeakHashMap<Integer, String>();
    numbers.put(new Integer(1), "one");// key only used within map not anywhere else
    numbers.put(new Integer(2), "two");
    System.out.println(numbers.get(new Integer(1))); // prints "one"
    System.gc();
    // let's say a garbage collection happens here
    System.out.println(numbers.get(new Integer(1))); // prints "null"
    System.out.println(numbers.get(new Integer(2))); // prints "null"


    Object key = new Object();
    m1.put(key, c1);
    System.out.println(m1.size());
    key = null or new Object() ; // privious key only used within map not anywhere else
    System.gc();
    Thread.sleep(100);
    System.out.println(m1.size());
Run Code Online (Sandbox Code Playgroud)

Bor*_*der 2

这是因为当对象不再具有来自程序任何其他部分的强引用时,它们将被垃圾回收 (GC)。

给定一个WeakHashMap<MyObject, String>then 如果我们执行以下操作:

MyObject mo = new MyObject();
map.put(mo, "Test");
mo = null;
Run Code Online (Sandbox Code Playgroud)

然后该参赛作品mo -> Test将有资格获得 GC。这意味着,如果您有一个.equals使用 的某些属性MyObject来测试相等性的自定义实现,那么您以后无法执行此操作:

MyObject mo2 = new MyObject();
map.get(mo2);
Run Code Online (Sandbox Code Playgroud)

因为即使您的重写.equals方法可能会说mo2.equals(mo) == true情况并非如此mo2 == mo,因此该条目可能已经被 GC 了。

要点是,如果您保留对的引用mo并使用它来检索值,Map那么该引用必须如此== mo,因此有两件事是正确的:

  1. 该条目mo -> Test不能被 gced
  2. 您可以使用==基于.equals方法从地图中检索条目

基本上; 由于 GC 将使用强引用来测试对象是否可以被 GC,因此最好确保您的.equals方法执行相同的操作以避免混淆。