当有HashMap和Concurrenthashmap时,WeakHashMap的目的是什么?

时间:2013-08-27 17:41:41

标签: java hashmap java.util.concurrent concurrenthashmap weakhashmap

当已经有其他实现可用时,需要引入Weak HashMap。

简而言之,我有两个问题:

  
      
  • Why jdk has WeakHashMap when there is HashMap and Concurrent HashMap in java ?

  •   
  • What is the use of it in real life applications ?

  •   

编辑:

  

虽然WeakHashmap键是一个弱引用,但它们仍然引用   比WeakHashMap中的GC丢弃键更基于什么。

6 个答案:

答案 0 :(得分:4)

  

WeakReferences和WeakHashMaps的一个常见用途是   向对象添加属性。偶尔你想添加一些   对象的功能或数据,但是子类化和/或组合   在这种情况下,不是一个明智的选择   创建一个hashmap,链接您要扩展到该属性的对象   你想要添加。然后,只要你需要房产,你可以看看   它在地图上。但是,如果要添加属性的对象   往往会被摧毁并创造很多,你最终可能会得到很多   地图中的旧对象占用了大量内存

     

如果您使用WeakHashMap,则对象会将您的地图保留为   一旦它们不再被你的程序的其余部分使用,那就是   期望的行为。

WeakHashMap的关键字有弱引用。如果密钥已被垃圾收集,则WeakHashMap对象中的条目将自动删除。它不会发生在正常的HashMap中。如果密钥是垃圾回收,则不会删除该条目。

在示例中,我选择了一个HashMap和一个WeakHashMap。我将把对象放入对象中,然后我们将引用键作为null然后进行垃圾收集。再次检查条目。在HashMap对象条目中将存在,但在WeakHashMap对象中将不存在条目。

import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;

public class WeakHashMapTest {
    public static void main(String[] args) {
        Map hashMap= new HashMap();

        Map weakHashMap = new WeakHashMap();

        String keyHashMap = new String("keyHashMap");
        String keyWeakHashMap = new String("keyWeakHashMap");

        hashMap.put(keyHashMap, "Ankita");
        weakHashMap.put(keyWeakHashMap, "Atul");
        System.gc();
        System.out.println("Before: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap"));

        keyHashMap = null;
        keyWeakHashMap = null;

        System.gc();  

        System.out.println("After: hash map value:"+hashMap.get("keyHashMap")+" and weak hash map value:"+weakHashMap.get("keyWeakHashMap"));
    }
}

输出结果为:

Before: hash map value:Ankita and weak hash map value:Atul
After: hash map value:Ankita and weak hash map value:null

更多信息:

答案 1 :(得分:1)

与普通集合不同,普通集合在您决定清除数据之前保存数据,WeakHashMap中的数据可能会在任何时间点被删除,而在JVM决定要内存恢复时没有通知。这使它适用于各种缓存目的。

您可以阅读弱引用(以及其他各种相关类型)here

答案 2 :(得分:1)

首先,您应该了解WeakReferences的目的。一旦您理解了这一点,那么从文档中阅读WeakedHashMap定义就可以清楚地说明其目的

  

具有弱键的基于哈希表的Map实现。一个条目   当其密钥不再存在时,将自动删除WeakHashMap   普通使用。更确切地说,存在给定的映射   key不会阻止密钥被垃圾丢弃   收集器,即最终确定,最终确定,然后回收。   当一个密钥被丢弃时,其条目将被有效地删除   地图,所以这个类的行为与其他Map的行为有些不同   的实施方式。

答案 3 :(得分:0)

您可以将对象用作键而不会阻止其被收集。

来自WeakHashMap documentation

  

当一个键被丢弃时,它的条目被有效地从地图中移除,所以这个类的行为与其他Map实现有些不同。

答案 4 :(得分:0)

它们提供了一种将对象用作键的方法,而无需创建对它的强引用。这是一个很好的做法,您不希望阻碍JVM对垃圾收集对象的能力,但仍然希望能够跟踪对象的某些方面。这使它们成为缓存或存储有关对象的元数据的理想选择。

答案 5 :(得分:0)

从答案来看,唯一的缓存功能是在GC上自动驱逐,它可能不会在年轻的GC期间发生,但在终身老式GC中用于缓存大型文件的使用时间。该条目是在任何GC上被驱逐还是仅在终生代已满?

除了不可预测的驱逐之外,没有可以在地图上指定的大小约束,因此任何具有预定义缓存大小(元素数量和内存大小)的缓存库以及驱逐策略对我来说似乎都是更好的选择。大多数缓存还包括在堆使用超出特定大小时减少大小/刷新更多元素的规定。这些还在并发期间提供了一致性。

所以,我想知道是否有一个好的用例除了由于设计不良而导致内存泄漏和错过命中的风险时使用它。