Перейти к основному содержимому

Где хранится длина массива в JVM?

· 2 мин. чтения

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 .