OpenJDK 19 и сжатые указатели

Мне трудно понять, как работают сжатые указатели в Java 19, помощь приветствуется.

В Java 11 эталонный размер равен 4 для кучи меньше 32 ГБ (сжатые указатели) и 8 для кучи большего размера. В Java 19 кажется, что они занимают 4 байта даже для больших куч (как?).

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

Версии Java: OpenJDK Java 11.0.12 и OpenJDK Java 19.0.1.

Командные строки:

-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -Xlog:gc+heap+coops -Xms41g -Xmx41g -XX:+AlwaysPreTouch

-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -Xlog:gc+heap+coops -Xms31g -Xmx31g -XX:+AlwaysPreTouch

Код: https://github.com/cornelcreanga/fun/blob/master/src/main/java/com/ccreanga/various/RandomAllocate.java — код взят с https://shipilev.net/jvm/anatomy -кварки/23-сжатые ссылки/

Запустите этот код как с Java 11, так и с Java 19, и вы увидите, что размер памяти в Java 19 меньше, чем в Java 11, для кучи > 32 ГиБ. Для меньшей кучи размер почти идентичен.

1 ответ

Вы смотрите на макетbyte[]массив и экземплярjava.lang.Object. Ни один из них не содержит ссылки на объект внутри кучи.

Разница, которую вы видите, заключается в размере указателя класса , который не указывает на место внутри кучи памяти. Но по историческим причинам вариант-XX:+UseCompressedClassPointersбыл связан с наличием-XX:+UseCompressedOopsвариант. Поэтому, когда размер кучи запрещал сжатые указатели на объекты, сжатые указатели классов отключались как побочный эффект.

JDK-8241825, сделать сжатые oops и сжатые указатели классов независимыми адресами, и это было решено с помощью JDK15.

Поэтому, когда я изменяю вашу программу на

      System.out.println(ClassLayout.parseInstance(new Object[3]).toPrintable());

и запустить его с кучей 41 ГБ, я получаю

      [Ljava.lang.Object; object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   8                    (object header: class)    0x000001f54bec41e0
 16   4                    (array length)            3
 20   4                    (alignment/padding gap)
 24  24   java.lang.Object Object;.<elements>        N/A
Instance size: 48 bytes
Space losses: 4 bytes internal + 0 bytes external = 4 bytes total

до JDK15 и

      [Ljava.lang.Object; object internals:
OFF  SZ               TYPE DESCRIPTION               VALUE
  0   8                    (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   4                    (object header: class)    0x000020fc
 12   4                    (array length)            3
 16  24   java.lang.Object Object;.<elements>        N/A
Instance size: 40 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

с JDK15 или новее.

Разница явно вызвана указателем класса и дополнением, но для трех ссылок на объекты требуется 24 байта в каждой версии JVM.

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