Java HashMap.clear()和remove()的内存有效吗?

考虑下面的HashMap.clear()代码:

  /** * Removes all of the mappings from this map. * The map will be empty after this call returns. */ public void clear() { modCount++; Entry[] tab = table; for (int i = 0; i < tab.length; i++) tab[i] = null; size = 0; } 

看来, Entry对象的内部数组( table )永远不会收缩。 所以,当我将10000个元素添加到地图中,然后调用map.clear() ,它将在内部数组中保留10000个空值。 所以,我的问题是,JVM如何处理这个没有任何数组的数组,因此HashMap内存是有效的?

这个想法是,只有当你想重新使用HashMap时才调用clear() 。 应该只重复使用一个对象,原因与之前使用的相同,所以有可能会有大致相同数目的条目。 为了避免无用缩小和调整Map的大小,当clear()被调用时,容量保持不变。

如果你所要做的只是放弃Map的数据,那么你不需要(实际上不应该)调用clear() ,而只需要清除对Map本身的所有引用,在这种情况下它将被垃圾回收最终。

看看源代码 ,它看起来像HashMap永远不会缩小。 resize方法被调用来在需要的时候加倍大小,但没有任何东西ala ArrayList.trimToSize()

如果你使用的是一个HashMap ,它的增长和收缩速度都很快,你可能只需要创build一个新的HashMap而不是调用clear()

你是对的,但是考虑到增加数组是一个非常昂贵的操作,HashMap认为“一旦用户增加了数组,然后再次需要这个数组的大小”并不是不合理的,数组而不是减less它,并冒着不得不昂贵地再扩展它。 我猜 – 这是一个启发式的方法 – 你也可以提倡另一种方式。

另外要考虑的是table中的每个元素都只是一个参考。 将这些条目设置为null将从Map的项目中删除引用,然后这些引用可以被垃圾收集使用。 所以不是你没有释放任何记忆。

但是,如果你需要释放Map本身使用的内存,那么你应该按照Joachim Sauer的build议释放它。