I have a problem with objects footprint understanding:
I'm running the following lines in two cases A and B
out.println(VM.current().details());
HashMap<Integer, Integer> hashMap = new HashMap<>();
A:
for (int i = 0; i < 1000; i++) {
hashMap.put(i, i);
}
B:
for (int i = 0; i < 1000; i++) {
hashMap.put(1000 + i, i);
}
PrintWriter pw = new PrintWriter(out);
pw.println(GraphLayout.parseInstance(hashMap).toFootprint());
Case A result is:
java.util.HashMap@1f89ab83d footprint:
COUNT AVG SUM DESCRIPTION
1 8208 8208 [Ljava.util.HashMap$Node;
1872 16 29952 java.lang.Integer
1 48 48 java.util.HashMap
1000 32 32000 java.util.HashMap$Node
2874 70208 (total)
Case B result is:
java.util.HashMap@1f89ab83d footprint:
COUNT AVG SUM DESCRIPTION
1 8208 8208 [Ljava.util.HashMap$Node;
2000 16 32000 java.lang.Integer
1 48 48 java.util.HashMap
1000 32 32000 java.util.HashMap$Node
3002 72256 (total)
The difference between A and B is 128 instances of Integer (1872 vs 2000). The first assumption was an IntegerCache affects but it does not explain case B in my mind.
The question: why these two footprints are different?
details:
jol: "org.openjdk.jol:jol-core:0.8"
# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
...
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
Java indeed has a cache for
Integerinstances with values between -128 and 127 (when using auto-boxing orInteger.valueOf(int)directly). Thusput(i,i)will use the same instance whereasput(1000 + i, i)or evenput(1000 + i, 1000 + i)won't.put(i,i)will use the cache for values 0 to 127 (i.e. 128 instances) and return the sameIntegerinstance in both cases.put(1000 + i,i)will create a newIntegerinstance for the key but use the cache for values 0 to 127 (i.e. 128 instances)put(1000 + i, 1000 + i)will create newIntegerinstances for both the key and the value even though they have the same numerical value. Thus if you'd do that you should see 128 additionalIntegerinstance be created.