java - HashMap 内存开销

标签 java memory hashmap

我在研究 Hash Map 的内部结构时遇到了以下细节:

  • 实现是一个 HashMap$Entry 对象的数组:

  • 每个 HashMap$Entry 包含: – int key 哈希 – 下一个对象 – 对象键 – 对象值

  • 默认容量为 16 个条目

  • 空大小为128字节

  • HashMap 的开销是 48 字节,加上 (16 + (entries * 4bytes)) array – 加上 HashMap$Entry 对象的开销

  • 每个键 ↔ 值条目额外 32 字节 HashMap 的开销是
    因此:– 48 字节,加上每个条目 36 字节

谁能解释一下“HashMap 的开销是 48 字节,加上 (16 + (entries * 4bytes)) array""每个 key ↔ value entry 额外 32bytes HashMap 的开销是
因此:– 48 字节,加上每个条目 36 字节”
???

我不明白这些结论是如何得出的,即我们是如何发现关于 HashMap 的最终内存细节的。

最佳答案

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

But let's see for ourselves对于 OpenJDK 7,HashMap 类:


Overhead is 48 bytes for HashMap

客房服务信息。 大概是 8 个字节。

实现中有三个字段,用于保存由 keySet()values()entrySet() 方法生成的 View 。三个指针,在 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[] 表)。 4 个字节。

(static final 字段不算在内,它们是编译时常量)

所有这些都为我们提供了 40 字节 HashMap 实例的固定成本。它不是 48 字节,我不知道为什么。也许我错过了什么,也许你的文字提到了其他版本。这些事情有时会发生一些变化。过去可能有一个额外的字段。也许它从 40 字节填充到 48 字节(但它不应该)。


16 + (entries * 4 bytes) for array

Entry[]表表是在构造HashMap时实例化的,我们也需要对它进行计数。

一个实例化的数组需要 8 个字节 的管理数据,4 个字节 用于length 属性。那是 12 个字节,而不是 16 个。同样,不知道它来自哪里。

每个条目都是指向 Entry 对象的指针,因此每个条目 4 个字节。这很容易。


Additional 32 bytes per key ↔ value entry

同样,8 字节的内务处理。

现在,字段:

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 虚拟机吗?那可能是 64 位操作系统吗?也许现在的管家信息是 16 个字节(Java 8 会改变什么吗?)。

无论如何,我尝试尽我所知计算内存消耗。

关于java - HashMap 内存开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20175225/

相关文章:

java - 如何从 ArrayList<HashMap<String, String>> android 中获取所有元素

java - 我如何在Android上使用Soap从Web服务发送和接收Hashmap

java - java中将ResultSet转换为HashMap的List

java - jni xlib 窗口句柄

memory - RabbitMQ + 内存限制

java - "NegativeArraySizeException"- 自定义类加载器

c - 指针与堆中内存的关系

java - 等到使用 Latch 执行 Platform.runLater

java - 找不到元素 'beans' 的声明

java - 尝试了解 Android 中的 XML Pull 解析器 - Java