当前位置: 首页 > 面试题库 >

哈希表使用多少内存?

潘胤
2023-03-14
问题内容

在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个字节的对象开销。我不确定是否为空-可能会以某种方式压缩空指针。



 类似资料:
  • 请帮助选择如何存储消息: 1) 2) SET似乎比LIST更容易使用,但Redis会在每条消息中存储字段名,从而使内存使用量增加一倍吗?

  • keys 一个包含哈希表中查找到的键的序列。 请注意,并不是所有的哈希表都支持这个 (询问程序员一个指定的哈希表是否允许这么操作)。 <#assign h = {"name":"mouse", "price":50}> <#assign keys = h?keys> <#list keys as key>${key} = ${h[key]}; </#list> 将会输出: name = mouse

  • 哈希表 通过最简单的取模运算作为哈希算法 class HashNode(object): def __init__(self, id, data): self.id = id self.data = data self.next = None def __str__(self): return '(%d,%s)' %

  • REDIS_HASH (哈希表)是 HSET 、 HLEN 等命令的操作对象, 它使用 REDIS_ENCODING_ZIPLIST 和 REDIS_ENCODING_HT 两种编码方式: 字典编码的哈希表 当哈希表使用字典编码时, 程序将哈希表的键(key)保存为字典的键, 将哈希表的值(value)保存为字典的值。 哈希表所使用的字典的键和值都是字符串对象。 下图展示了一个包含三个键值对的哈希

  • Hashtbl 模块 Hashtbl模块实现了一个高效的,可变的查询表。如下创建一个哈希表: # let my_hash = Hashtbl.create 123456;; val my_hash : ('_weak1, '_weak2) Hashtbl.t = <abstr> 这个123456是哈希表的初始大小。这个值可以是你对数据量的一种猜测,但是哈希表有可能会 随着数据量的增多而变大,因此

  • 问题内容: 当大小超过maxthreshold值时,如何在哈希表或哈希表中进行重新哈希处理? 是否所有对都已复制到新的存储桶阵列中? 编辑: 重新哈希后,同一存储桶(位于链接列表中)中的元素会发生什么情况?我的意思是说,他们在重新哈希处理后会留在同一个桶中吗? 问题答案: 问题中的最大阈值称为负载系数。 建议负载系数约为0.75。负载因子定义为(m / n),其中n是哈希表的总大小,m是在需要增加