«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. Длина массива
JVM HotSpot использует структуру данных, называемую Ordinary Object Pointers (OOP), для представления указателей на объекты. Чтобы быть более конкретным, HotSpot JVM представляет массивы с помощью специальной ООП, называемой arrayOop. Каждый arrayOop включает в себя заголовок объекта со следующими сведениями:
-
Одно слово метки для хранения идентификационного хэш-кода или информации GC Одно слово klass для хранения общих метаданных класса 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.