«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.