2013-11-24 60 views
4

我正在学习有关哈希映射的内部结构,其中我碰到下面的信息传来:哈希映射内存开销

  • 实施是的HashMap $ Entry对象数组:

  • 每个的HashMap $条目包含: - INT KeyHash - 对象接下来 - 对象键 - 客体的价值

  • 默认容量为16 entri ES

  • 空大小为128个字节

  • 开销为 阵列48个字节用于HashMap中,加号(16 +(条目* 4字节)) - 加的HashMap $条目的开销对象

  • 附加32字节每键↔HashMap中的值条目架空因此
    : - 48个字节,加上每个条目为36字节

任何人都可以请求本身解释我“开销为HashMap的48个字节,加上(16 +(条目* 4字节)),用于 阵列”“每个键附加32字节↔HashMap中的值条目开销
因此: - 48个字节,加每个条目36字节“
???

我不明白这些结论是如何得出的,即我们如何看到这个最终记忆有关散列图的细节。

回答

2

You might want to read this SO question.在不同的CPU架构,VM实现以及不同的Java版本之间(例如OOPS,还有fixnums等的建议),对象开销会有所不同。

But let'ssee for ourselves为的OpenJDK 7,HashMap类:


开销为HashMap

家政信息48个字节。 大概8个字节。

执行过程中有三个字段保存keySet(),values()entrySet()方法的视图。三位指针,即32位机器上的12字节

// from AbstractMap 
transient volatile Set<K>  keySet = null; 
transient volatile Collection<V> values = null; 

// from HashMap 
private transient Set<Map.Entry<K,V>> entrySet = null 

有三个int字段:sizethresholdmodCount12个字节。

有一个float场:loadFactor4个字节。

表格指针本身(Entry[] table)。 4个字节。

(在static final领域不计,它们是编译时间常数)

所有这一切使我们40字节一个HashMap实例的固定费用。这不是48个字节,我不知道为什么。也许我错过了一些东西,也许你的文字提到了其他版本。这些东西有时候会有所改变。过去可能有一个额外的领域。也许它从40到48字节填充(但不应该)。


16 +(条目* 4个字节),关于阵列

Entry[] table表被实例化的HashMap被构造时,我们需要计算这一点。

一个实例化的数组需要8字节管理数据,4 byteslength属性。这是12字节,而不是16.再次,不知道从哪里来。

每个条目都是指向一个Entry对象的指针,所以这是4个字节每个条目。那很简单。每个键↔值条目

再次,8字节看家


附加32个字节。

现在,字段:

final K key; // a reference, 4 bytes 
V value;  // a reference, 4 bytes 
Entry<K,V> next; // a reference, 4 bytes 
final int hash; // an integer primitive, 4 bytes 

16个字节。

这是最终计数24字节每个条目。再次,这不是36.


我不知道你从那里得到的数字来自哪里。那可能是IBM vm吗?这可能是一个64位的操作系统?也许现在看家信息是16字节(Java 8会改变什么?)。

无论如何,我试图根据我的最佳知识来计算内存消耗。

+0

如果有人在我的计算中发现错误,请随时编辑我的帖子。 –