哈希映射内存开销
我正在研究哈希地图的内部结构,我遇到了以下细节:
-
实现是一个HashMap $ Entry对象的数组:
-
每个HashMap $ Entry包含: – int KeyHash – Object next – Object key – Object Value
-
默认容量为16个条目
-
空大小为128个字节
-
HashMap的开销是48个字节,对于数组加上(16 +(条目* 4个字节)) – HashMap $ Entry对象的开销
-
每个键的额外32字节↔值输入HashMap的开销是
因此: – 48个字节,每个条目加36个字节
任何人都可以解释我“HashMap的开销是48字节,加上(16 +(条目* 4字节))数组”和“每个键的额外32字节↔值条目HashMap的开销是
因此: – 48个字节,每个条目加36个字节“ ???
我无法理解这些结论是如何产生的,即我们如何遇到关于哈希映射的最终内存细节。
您可能想要阅读此SO问题。 对象开销将在不同的CPU架构,VM实现之间以及不同的Java版本之间变化(例如,OOPS,还有fixnums等的建议)。
但让 我们自己看看 OpenJDK 7, HashMap
类:
HashMap
开销是48个字节
家政信息。 大概是8个字节。
实现中有三个字段,用于保存由keySet()
, values()
和entrySet()
方法创建的视图。 三个指针,即32位机器上的12个字节 。
// from AbstractMap transient volatile Set keySet = null; transient volatile Collection values = null; // from HashMap private transient Set> entrySet = null
有三个int
字段: size
, threshold
和modCount
。 12个字节。
有一个float
字段: loadFactor
。 4字节。
表指针本身( Entry[] table
)。 4字节。
( static final
字段不计算,它们是编译时常量)
所有这些都为我们提供了一个HashMap
实例的40字节成本。 它不是48字节,我不知道为什么。 也许我错过了什么,也许你的文字提到了其他版本。 这些事情有时会有所改变。 过去可能有一个额外的领域。 也许它填充了40到48个字节(但它不应该)。
数组的16 +(条目* 4个字节)
在构造HashMap
时实例化Entry[] table
,我们也需要对它进行计数。
实例化的数组需要8个字节的内务处理数据, 4 bytes
用于length
属性。 这是12个字节 ,而不是16 个 。再次,不知道它来自哪里。
每个条目都是一个指向Entry
对象的指针,因此每个条目有4个字节 。 那很简单。
每个键Additional值输入附加32个字节
再次, 8字节的家务。
现在,领域:
final K key; // a reference, 4 bytes V value; // a reference, 4 bytes Entry next; // a reference, 4 bytes final int hash; // an integer primitive, 4 bytes
16个字节。
这是每个条目的最终计数为24个字节 。 再说一遍,那不是36。
我不知道你在那里得到的数字来自哪里。 那可能是IBM的虚拟机吗? 这可能是64位操作系统吗? 也许家政信息现在是16字节(Java 8会改变什么吗?)。
无论如何,我试图根据我的最佳知识计算内存消耗。