繁体   English   中英

Java HashSet <Long>需要多少内存

[英]How much memory Java HashSet<Long> should take

我想使用HashSet<Long>在内存中存储大量唯一数字。 我计算了要消耗的大概内存(64位指针大小):

Long会占用16个字节的空间。 所以最初我将条目数乘以16得到内存。 但实际上,每个条目的内存大大超过16个字节。 之后我研究了HashSet实现。 简而言之,在底层实现中,它实际上存储了每个hashset条目的额外虚拟对象(12个字节)。 并指向下一个条目的指针(8个字节)。 因此,每个条目承认额外的12 + 8字节。

因此每个条目的总内存:16 + 12 + 8 = 36个字节。 但是当我运行代码并检查内存时,每个条目仍然超过36个字节。

我的问题(简而言之)HashSet占用多少内存(例如,在64位机器上)?

您可以使用此测试准确测量此大小:

    long m1 = Runtime.getRuntime().freeMemory();
    // create object (s) here
    long m2 = Runtime.getRuntime().freeMemory();
    System.out.println(m1 - m2);

使用-XX:-UseTLAB选项运行

在我的64位HotSpot上,空HashSet需要480个字节。

为什么这么多? 因为HashSet具有复杂的结构(在调试模式下的btw IDE有助于查看实际字段)。 它基于HashMap(适配器模式)。 所以HashSet本身包含对HashMap的引用。 HashMap包含8个字段。 实际数据位于节点数组中。 Node有:int hash; K键; V值; 节点接下来。 HashSet仅使用键并将虚拟对象放入值中。

对象的大小是一个实现细节。 如果它在一个平台上是x个字节,则无法保证在另一个平台上它也是x个字节。

如你所知, Long是盒装的,但是16个字节是错误的。 原始long需要8个字节,但long周围的框的大小取决于实现。 根据这个Hotspot相关的答案开销词和填充意味着一个盒装的4字节int可以达到24个字节!

该(特定于Hotspot)答案中提到的字节对齐和填充也将应用于Entry对象,这也将推动消耗。

使用的内存是32 * SIZE + 4 * CAPACITY +(16 * SIZE)beign“SIZE”元素的数量。

HashMap的默认大小是16个HashMapEntry条目。 每个HashMapEntry上都有四个对象(int keyHash,Object next,Object key,Object value)。 因此,它通过包装元素来引入空条目的开销。 此外,hashmap的扩展速率为2x,因此对于17个元素,您将有32个条目,其中15个为空。

更简单的方法是使用内存分析器检查heapdump。

HashSet是一个复杂的野兽。 在审查了一些评论之后,这里有一些消耗内存的项目,你没有考虑到:

  1. Java集合(真集合,而不是普通数组)只能接受对象引用,而不是基元。 因此,您的long原语被装入java.lang.Long对象并添加到HashSet. Somebody mentioned that a的引用HashSet. Somebody mentioned that a HashSet. Somebody mentioned that a Long`对象将是24个字节。 加上参考,即8个字节。
  2. 哈希表桶是集合。 我不记得它们是数组还是ArrayListLinkedList等,但是因为散列算法可能产生冲突,所以必须将HashSet的元素放入集合中,这些集合由散列码组织。 最好的情况是只有1个元素的ArrayList :您的Long对象。 ArrayList的默认后备数组大小为10,因此在对象中有10个对象引用,因此每个Long现在至少有80个字节。 由于Long是一个整数,我怀疑散列算法可以很好地解决问题。 我不确定其值超过Integer.MAX_VALUE的long会发生什么。 由于生日悖论,这将不得不以某种方式发生冲突。
  3. 实际的哈希表HashSet基本上是一个HashMap ,其值HashMap 在引擎盖下,它创建了一个HashMap ,其中有一个桶数组来表示哈希表。 阵列大小基于容量,根据您添加的元素数量不明确。
  4. 为了使未来的增长更容易,哈希表的大小通常会有意地拥有比所需更多的桶。 希望它不是更多。 但是不要指望5个元素恰好需要5个桶。

长篇简短的哈希表是一种内存密集型数据结构。 这是空间/时间的权衡。 假设一个良好的散列分布,你可以获得额外的内存使用成本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM