如果我不注释第 1 行和第 2 行,则第 1 行会导致 OutOfMemoryError。如果我执行相反的操作,则不会导致 OutOfMemoryError,因为 i : 3869 Size : 3870 maxSize : 3870
。
来自 Java 文档:
Because the garbage collector may discard keys at any time, a WeakHashMap may behave as though an unknown thread is silently removing entries.
基于此语句大小应该减少,但第 3 行输出似乎不断增加。为什么会这样?
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
public class WrongWeakHashMapSize {
private static Map map = new HashMap();
public static void main(String[] args) {
for (int i = 0, maxSize = 0; i < 10000000L; ++i) {
/*
* Line 1 Causes java.lang.OutOfMemoryError: Java heap space Error.
* After this line i : 244 Size : 490 maxSize : 490.
*/
map.put(new LargeObject(i), new Integer(i)); // Line 1
/* After Commenting Line 1 :----
* Line 2 Does not Cause java.lang.OutOfMemoryError. Because of WeakReference class use.I think Line 3
* is showing wrong Size of MAP. it printed
* i : 3869 Size : 3870 maxSize : 3870 which seems almost impossible
* because 3870 objects of LargeObject can not be exist at a time.
*/
map.put(new WeakReference(new LargeObject(i)), new WeakReference(new Integer(i))); // Line 2
maxSize = maxSize < map.size() ? map.size() : maxSize; // Line 3
System.out.println("i : " + i + " Size : " + map.size() + " maxSize : " + maxSize); // Line 4
}
}
public static class LargeObject {
private final byte[] space = new byte[1024 * 1024];
private final int id;
public LargeObject(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
}
最佳答案
这是因为 map.size()
为您提供了 map 中键值对的数量。 弱
引用的垃圾收集不会从 map 中删除引用,它只会垃圾化对象。
WeakReference
的唯一影响是一些 LargeObject
和 Integer
将有资格被丢弃,关键是 -值映射仍然在 map 中,因此仍然被计算在内。
关于java - Java 中的 map 大小不正确。如果我将 Key 和 Value 包装在 WeakReference 中,然后添加到 HashMap 中,打印的大小与预期不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15567221/