1. Обзор
В этом кратком руководстве мы увидим, как и где JVM HotSpot хранит длину массива.
Обычно расположение областей данных времени выполнения в памяти не является частью спецификации JVM и оставлено на усмотрение разработчика . Поэтому у каждой реализации JVM может быть своя стратегия размещения объектов и массивов в памяти.
В этом руководстве мы сосредоточимся на одной конкретной реализации JVM: HotSpot JVM. Мы также можем взаимозаменяемо использовать термины JVM и HotSpot JVM.
2. Зависимость
Чтобы проверить расположение массивов в памяти в JVM, мы собираемся использовать инструмент Java Object Layout ( JOL ). Поэтому нам нужно добавить зависимость jol-core
:
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.10</version>
</dependency>
3. Длина массива
HotSpot JVM использует структуру данных, называемую обычными указателями объектов ( OOP ), для представления указателей на объекты. Чтобы быть более конкретным, JVM HotSpot представляет массивы с помощью специальной ООП, называемой arrayOop
. Каждый arrayOop
включает в себя заголовок объекта со следующими сведениями:
- Одно слово метки для хранения идентификационного хэш-кода или информации GC
- Одно слово класса для хранения общих метаданных класса
- 4 байта, представляющие длину массива
Поэтому JVM сохраняет длину массива в заголовке объекта .
Давайте проверим это, проверив структуру памяти массива:
int[] ints = new int[42];
System.out.println(ClassLayout.parseInstance(ints).toPrintable());
Как показано выше, мы анализируем структуру памяти из существующего экземпляра массива. Вот как JVM размещает int[]
:
[I object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1) # mark
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) # mark
8 4 (object header) 6d 01 00 f8 (01101101 00000001 00000000 11111000) (-134217363) #klass
12 4 (object header) 2a 00 00 00 (00101010 00000000 00000000 00000000) (42) # array length
16 168 int [I.<elements> N/A
Instance size: 184 bytes
Как упоминалось ранее, JVM хранит длину массива в заголовке объекта после слов mark и klass. Кроме того, длина массива будет храниться в 4 байтах, поэтому она не может превышать максимальное значение для 32-битного целого числа.
После заголовка объекта JVM сохраняет фактические элементы массива. Поскольку у нас есть массив из 42 целых чисел, общий размер массива составляет 168 байт — 42 умножить на 4.
4. Вывод
В этом коротком руководстве мы увидели, как JVM хранит длину массива.
Как обычно, все примеры доступны на GitHub .