HashMap.clear() 减少内存?

Ran*_* Ji 2 java memory hashmap

System.gc();
System.out.println((Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory())/1024/1024);// print 1M

Map map=new HashMap();
for(int i=0;i<100000;i++){
    map.put("key"+i,"i");
}
System.gc();
System.out.println((Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory())/1024/1024); //print 10M

map.clear();
System.gc();
System.out.println((Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()));//print less than 1M
Run Code Online (Sandbox Code Playgroud)

看来调用clear方法时内存会减少。然而,从其他答案来看,该clear方法似乎从未缩小HashMap. 那么为什么内存会减少呢?

T.J*_*der 7

如果您参考这个问题的答案table,他们会告诉您,中的条目数组 ( )HashMap永远不会缩小。相反,它的条目全部设置为null

但是,清除映射会使您创建的 100,000 个字符串("key0""key1"、 ...)及其关联Map.Entry对象符合垃圾回收的条件,尽管table没有变小。


Mic*_*ael 5

这是一个实现细节,因此确切的答案可能会根据 Java 的确切版本而变化。

这是 Java 8 的实现HashMap::clear

public void clear() {
    Node<K,V>[] tab;
    modCount++;
    if ((tab = table) != null && size > 0) {
        size = 0;
        for (int i = 0; i < tab.length; ++i)
            tab[i] = null;
    }
}
Run Code Online (Sandbox Code Playgroud)

桶表被完全清空,但表本身以及非默认容量被保留。

无论具体实现如何,您都希望释放大量内存,因为创建的所有非驻留字符串都"key"+i将有资格进行收集。

如果您确实关心将容量减少回默认值,那么只需使用新实例重新分配 HashMap 即可。