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)
这是因为当对象不再具有来自程序任何其他部分的强引用时,它们将被垃圾回收 (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,因此有两件事是正确的:
mo -> Test不能被 gced==基于.equals方法从地图中检索条目基本上; 由于 GC 将使用强引用来测试对象是否可以被 GC,因此最好确保您的.equals方法执行相同的操作以避免混淆。