哈希表使用多少内存?


问题内容

在Java中,如果我创建一个Hashtable<K, V>并将N个元素放入其中,它将占用多少内存?如果依赖于实现,那么什么才是好的“猜测”?


问题答案:

编辑; 噢,天哪,我是个白痴,我提供了HashMap的信息,而不是HashTable的信息。 但是,检查后,出于内存目的,实现是相同的。

这取决于您的VM的内部内存设置(项目的包装,32位或64位指针以及字对齐/大小),并且不是由Java指定的。

可以在这里找到有关估计内存使用量的基本信息。

您可以这样估算:

  • 在32位VM上,指针是4个字节,在64位VM上,指针是8个字节。
  • 对象开销是8个字节的内存(对于空对象,不包含任何内容)
  • 对象被填充为8字节(ugh)的倍数的大小。
  • 每个哈希图都有一个很小的,恒定的开销:一个浮点数,3个整数和对象开销。
  • 有一个插槽阵列,其中一些插槽将具有条目,其中一些插槽将保留给新插槽。填充插槽与总插槽的比率不超过构造函数中指定的负载系数。
  • 插槽数组需要一个对象开销,再加上一个int的大小,再加上每个插槽一个指针,以指示存储的对象。
  • 默认情况下,插槽数通常是存储映射数的1.3到2倍,默认的加载因子为0.75,但可能小于此值,具体取决于哈希冲突。
  • 每个存储的映射都需要一个入口对象。这需要一个对象开销,3个指针,再加上存储的键和值对象,再加上一个整数。

因此,将其放在一起(对于32/64位Sun HotSpot JVM):HashMap需要24字节(自身,原始字段)+
12字节(插槽数组常量)+每个插槽4或8个字节+每个条目+键的24/40字节对象大小+值对象大小+每个对象填充8字节的倍数

或者,大致(在大多数默认设置下,不能保证精确):

  • 在32位JVM上:36字节+ 32字节/映射+键和值
  • 在64位JVM上:36字节+ 56字节/映射+键和值

注意:这需要更多检查,在64位VM上可能需要12个字节的对象开销。我不确定是否为空-可能会以某种方式压缩空指针。