Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating memory requirements for HashMap in Java

I have a ConcurrentHashMap like so:

HashMap<String, Integer> fruitMap = new ConcurrentHashMap<>();

The key is a String of 10 characters, the value is an Integer.

Assuming there is no other memory consuming code in my application, how do I calculate the number of entries that can be stored in the HashMap on a server with 10GiB memory?

It'll be great if you can mention how we can calculate it for both Java 7 and Java 8 or later.

PS: I found this, but I didn't understand how the 6.75KB memory usage for hashmap of 100 ints mapped to ints was arrived at.

like image 567
seeker Avatar asked Jun 13 '26 10:06

seeker


1 Answers

I will only provide you an example against jdk-15 using JOL (that is the only reliable tool I would ever trust for this), for a ConcurrentHashMap with 10 entries, it is up to you from there.

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());

This will output:

 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)

Understanding the above is not trivial. Integer is the easiest one:

  • 12 bytes for two headers
  • 4 bytes for the inner int field

So 16 bytes for one, you have 10 of those, thus that line:

0        16       160   java.lang.Integer

an instance of String is more involved:

  • 12 bytes for headers
  • 4 bytes for hash field
  • 1 byte for coder field
  • 1 boolean for hashIsZero field (what is hashIsZero?)
  • 2 bytes for padding
  • 4 bytes for value (byte [])

So 24 bytes * 10:

 10        24       240   java.lang.String

That inner byte [] will also add:

  • 12 bytes of headers (byte[] is an Object).
  • 4 bytes for the length field
  • 10 bytes for each of the 10 bytes
  • 6 bytes padding

Thus that:

 10        32       320   [B

Getting the overall picture is left as an exercise to you.

like image 157
Eugene Avatar answered Jun 17 '26 10:06

Eugene



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!