Hashtable使用多少内存?

8

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


除了小型映射表之外,它很可能会受到键和值对象大小的影响。 - Tom Hawtin - tackline
我已经添加了精确计算,尽管它可能会因虚拟机而异。这并不总是正确的。对于非常小的键和值(比如说,使用基本类型的包装对象),Entry 对象的大小可能会超过 hashmap/hashtable 的大小(内部它们是相同的)。如果多个值引用同一个对象实例,也可能发生这种情况。如果您正在使用大量基本对象作为键或值,请查看 Trove 库。它对此更快且更节省内存。 - BobMcGee
2个回答

14

编辑; 哎呀,我真是傻瓜,我给出的信息是HashMap而不是HashTable。 但是,检查后,它们的实现在内存方面是相同的。

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

有关估计内存使用情况的基本信息可以在此处找到。

您可以这样估算:

  • 在32位VM上,指针占用4个字节,在64位VM上,它占用8个字节。
  • 对象开销为8个字节的内存(对于一个空对象,不包含任何内容)
  • 对象填充到8字节的倍数大小(啊)。
  • 每个哈希映射都有一个小的常数开销:一个浮点数,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位虚拟机可能需要12字节的对象开销。我不确定空值——空指针可能以某种方式被压缩。


4

这很难估计。我建议您首先阅读以下内容:

http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html

只需使用sunjdk工具来查找K、V和的大小

jmap -histo [pid]

num #instances #bytes class name

1: 126170 19671768 MyKClass

2: 126170 14392544 MyVClass

3: 1 200000 MyHashtable

如果不需要同步,则可以使用HashMap代替Hashtable。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接