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.