UseCompressedOops UseCompressedClassPointers в jdk-13 и jdk-15
Случайно я наткнулся на изменение jdk-15
что я не знал. Предположим, у меня очень простой вопрос: каков размер массива из 3-х промежуточных чисел? Для этого я использую JOL. Код довольно тривиальный:
import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;
public class Array {
public static void main(String [] args){
int [] array = new int[3];
System.out.println(ClassLayout.parseInstance(array).toPrintable());
}
}
Я управляю этим с jdk-13
:
java -Djdk.attach.allowAttachSelf -Djol.tryWithSudo=true -cp jol-cli.jar Array.java
Получаю вывод:
[I object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 18 0e 07 00 (00011000 00001110 00000111 00000000) (462360)
12 4 (object header) 03 00 00 00 (00000011 00000000 00000000 00000000) (3)
16 12 int [I.<elements> N/A
28 4 (loss due to the next object alignment)
Instance size: 32 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
Это довольно очевидно:
12 bytes --> Object headers
4 bytes --> size of array
12 bytes --> elements of array themselves
4 bytes --> padding to align by 8 bytes
----
32 bytes total
Запуск этого примера с jdk-15
дает тот же результат, тот же 32 bytes
. Ожидается...
Во второй части я хочу отключить оптимизацию JVM: -XX:-UseCompressedOops
. Я управляю этим сjdk-13
:
java -Djdk.attach.allowAttachSelf -Djol.tryWithSudo=true -cp jol-cli.jar -XX:-UseCompressedOops Array.java
[I object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 11 00 00 00 (00010001 00000000 00000000 00000000) (17)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 40 0c f0 33 (01000000 00001100 11110000 00110011) (871369792)
12 4 (object header) 02 00 00 00 (00000010 00000000 00000000 00000000) (2)
16 4 (object header) 03 00 00 00 (00000011 00000000 00000000 00000000) (3)
20 4 (alignment/padding gap)
24 12 int [I.<elements> N/A
36 4 (loss due to the next object alignment)
Instance size: 40 bytes
Space losses: 4 bytes internal + 4 bytes external = 8 bytes total
Ну вроде и ожидалось:
16 bytes --> object headers (I did -XX:-UseCompressedOops after all)
4 bytes --> array size
4 bytes --> alignment for array headers (AFAIK this is only done for arrays)
12 bytes --> array elements themselves
4 bytes --> 4 bytes padding
----
40 bytes total
Теперь давайте запустим тот же пример с jdk-15
:
[I object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 0e 09 00 00 (00001110 00001001 00000000 00000000) (2318)
12 4 (object header) 03 00 00 00 (00000011 00000000 00000000 00000000) (3)
16 12 int [I.<elements> N/A
28 4 (loss due to the next object alignment)
Instance size: 32 bytes
Почему это 32 bytes
сейчас же? Почему нет40
, как и с jdk-13
?
1 ответ
В обоих jdk-13
а также jdk-15
, оба эти параметра включены по умолчанию:
java -XX:+PrintFlagsFinal -version | grep Compressed
bool UseCompressedClassPointers = true
bool UseCompressedOops = true
когда -XX:-UseCompressedOops
отключен, это означает, что UseCompressedClassPointers
тоже отключен. Вот почему когдаUseCompressedOops
выключен, размер заголовка увеличивается на 4 bytes
, так как UseCompressedOops
выключает UseCompressedClassPointers
. По крайней мере, так оно и есть вjdk-13
:
java -XX:+PrintFlagsFinal -XX:-UseCompressedOops -version | grep Compressed
bool UseCompressedClassPointers = false
bool UseCompressedOops = false
Все изменилось в jdk-15
:
bool UseCompressedClassPointers = true
bool UseCompressedOops = false
Так отключение UseCompressedOops
не означает, что UseCompressedClassPointers
также отключен, поэтому он остается на 4 bytes
.
Хотя, я сам на это ответил, было бы неплохо, если бы кто-нибудь нашел для этого соответствующую ошибку / изменение? Пока мне это не удалось.