计算Java中HashMap的内存需求

see*_*ker 2 java memory hashmap

我有一个像这样的 ConcurrentHashMap:

HashMap<String, Integer> fruitMap = new ConcurrentHashMap<>();
Run Code Online (Sandbox Code Playgroud)

键为String10 个字符,值为Integer

假设我的应用程序中没有其他消耗内存的代码,如何计算具有 10GiB 内存的服务器上的 HashMap 中可以存储的条目数?

如果您能提及我们如何针对 Java 7 和 Java 8 或更高版本计算它,那就太好了。

PS:我找到了这个,但我不明白100个整数映射到整数的哈希图的6.75KB内存使用量是如何得出的。

Eug*_*ene 5

我只会向您提供一个反对jdk-15使用JOL 的示例(这是我信任的唯一可靠工具),对于ConcurrentHashMap10 个条目,这取决于您。

Map<String, Integer> throttleMap = new ConcurrentHashMap<>();

for(int i = 0; i< 10; ++i){
    throttleMap.put((""+i).repeat(10), i);
}

System.out.println( GraphLayout.parseInstance((Object)throttleMap).toFootprint());
Run Code Online (Sandbox Code Playgroud)

这将输出:

 COUNT       AVG       SUM   DESCRIPTION
    10        32       320   [B
     1        80        80   [Ljava.util.concurrent.ConcurrentHashMap$Node;
    10        16       160   java.lang.Integer
    10        24       240   java.lang.String
     1        64        64   java.util.concurrent.ConcurrentHashMap
    10        32       320   java.util.concurrent.ConcurrentHashMap$Node
    42                1184   (total)
Run Code Online (Sandbox Code Playgroud)

理解以上内容并非易事。Integer是最简单的一个:

  • 两个标头各 12 个字节
  • 内部 int 字段占 4 个字节

因此16 bytes,对于其中一个,您有 10 个,因此这一行:

0        16       160   java.lang.Integer
Run Code Online (Sandbox Code Playgroud)

String一个更复杂的例子:

  • 12 字节用于标头
  • hash字段4 个字节
  • 1 个字节用于coder字段
  • 1 个布尔值字段hashIsZero什么是 hashIsZero?
  • 2 个字节用于填充
  • value( byte [])为 4 个字节

所以24 bytes*10:

 10        24       240   java.lang.String
Run Code Online (Sandbox Code Playgroud)

该内部byte []还将添加:

  • 12 字节的标头(byte[]是一个对象)。
  • 4个字节的length字段
  • 10个字节每10个字节
  • 6字节填充

因此:

 10        32       320   [B
Run Code Online (Sandbox Code Playgroud)

了解整体情况留给您作为练习。