jol footprint из HashMap<Целое число, Целое число>

У меня проблема с пониманием отпечатка объекта:

Я запускаю следующие строки в двух случаях A и 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());

Случай А результат:

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)

Случай B результат:

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)

Разница между A и B составляет 128 экземпляров Integer (1872 против 2000). Первое предположение было IntegerCache влияет, но это не объясняет случай B на мой взгляд.

Вопрос: почему эти два следа разные?

подробности:

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]

1 ответ

Решение

У Java действительно есть кеш для Integer экземпляры со значениями от -128 до 127 (при использовании автобокса или Integer.valueOf(int) напрямую). таким образом put(i,i) будет использовать тот же экземпляр, тогда как put(1000 + i, i) или даже put(1000 + i, 1000 + i) не будет.

put(i,i) будет использовать кэш для значений от 0 до 127 (т.е. 128 экземпляров) и вернет то же самое Integer экземпляр в обоих случаях.

put(1000 + i,i) создаст новый Integer экземпляр для ключа, но используйте кэш для значений от 0 до 127 (т.е. 128 экземпляров)

put(1000 + i, 1000 + i) создаст новый Integer экземпляры для ключа и значения, даже если они имеют одинаковое числовое значение. Таким образом, если вы сделаете это, вы должны увидеть 128 дополнительных Integer экземпляр будет создан.

Другие вопросы по тегам