哈希表使用多少内存?
-
07-07-2019 - |
题
在Java中,如果我创建一个 Hashtable<K, V>
放入N个元素,会占用多少内存?如果它依赖于实现,那么什么是一个好的“猜测”?
解决方案
编辑; 哦天哪,我是个白痴,我提供了 HashMap 的信息,而不是 HashTable 的信息。然而,经过检查,出于内存目的,实现是相同的。
这取决于 VM 的内部内存设置(项目打包、32 位或 64 位指针以及字对齐/大小),并且不是由 java 指定的。
可以找到有关估计内存使用情况的基本信息 这里.
你可以这样估计:
- 在 32 位 VM 上,指针为 4 字节,在 64 位 VM 上,指针为 8 字节。
- 对象开销是 8 个字节的内存(对于空对象,不包含任何内容)
- 对象的大小被填充为 8 字节的倍数(呃)。
- 每个哈希图都有一个小的、恒定的开销:1 个浮点数、3 个整数,加上对象开销。
- 有一个插槽数组,其中一些将有条目,其中一些将为新条目保留。已填充槽与总槽的比率不超过构造函数中指定的负载系数。
- 槽数组需要一个对象开销,加上一个 int 大小,再加上每个槽一个指针,以指示存储的对象。
- 默认负载因子为 0.75 时,槽的数量通常是存储映射数量的 1.3 到 2 倍,但也可能小于此值,具体取决于哈希冲突。
- 每个存储的映射都需要一个条目对象。这需要 1 个对象开销,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 个字节。我不确定空值——空值的指针可能会以某种方式被压缩。
其他提示
很难估计。我先读这个: http://www.codeinstructions.com/2008/12/ Java的对象存储器-structure.html
只需使用sunjdk工具来计算K,V和
的大小jmap -histo [pid]
num #instances #bytes类名
1:126170 19671768 MyKClass
2:126170 14392544 MyVClass
3:1 200000 MyHashtable
如果您不需要同步,也可以使用HashMap而不是Hashtable。
不隶属于 StackOverflow