java - Java 中的 map 大小不正确。如果我将 Key 和 Value 包装在 WeakReference 中,然后添加到 HashMap 中,打印的大小与预期不同

标签 java garbage-collection weak-references soft-references

如果我不注释第 1 行和第 2 行,则第 1 行会导致 OutOfMemoryError。如果我执行相反的操作,则不会导致 OutOfMemoryError,因为 包含在 WeakReference 中。但我无法理解第 3 行的输出 ---- 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 的唯一影响是一些 LargeObjectInteger 将有资格被丢弃,关键是 -值映射仍然在 map 中,因此仍然被计算在内。

关于java - Java 中的 map 大小不正确。如果我将 Key 和 Value 包装在 WeakReference 中,然后添加到 HashMap 中,打印的大小与预期不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15567221/

相关文章:

c# - 为什么 GC 在我引用它时收集我的对象?

c# - 如何在对目标的引用较弱的情况下将 Action 传递给任务工厂

c# - 如何在 .NET 4.x 中强制进行完全垃圾回收?

.net - 有没有办法在CLR中创建WeakList或WeakCollection(如WeakReference)?

java - (JavaFX 8) css 按钮边框和背景色问题

java - Java Flight Recorder 结果中的垃圾收集统计信息

java - 内存不足错误 : Java heap memory (GC heap)

java - 收到交易后如何在BitcoinJ中找到发件人比特币地址

java - 安卓数据库创建

java - 如何在Java EE环境中使用MySql处理外来字符