Структура объектов Java в памяти

Java

1. Схема памяти

Структура объектов, хранящихся в памяти, состоит из трех частей: заголовка объекта, данных экземпляра и заполнения выравнивания.


  1. заголовок объекта

    MarkWord (отметить поле): хэш-код, возраст генерации, флаг блокировки, смещенный идентификатор потока, смещенная отметка времени и другая информация. Mark Word разработан как нефиксированная структура данных, чтобы хранить как можно больше информации в очень небольшом пространстве, и он будет повторно использовать свое собственное пространство для хранения в соответствии с состоянием объекта. Исключение: если это массив, должна быть область для хранения размера массива, потому что нет возможности подтвердить размер массива из метаданных, поэтому он должен храниться в MarkWord объекта. заголовок.

    MarkWord различает разные биты состояния в зависимости от состояния объекта, тем самым различая разные структуры хранения. Например, следующая картинка:


    Другой частью заголовка объекта является указатель типа (Klass Pointer).

    Klass Pointer (указатель типа):То есть указатель на метаданные класса текущего объекта, и виртуальная машина использует этот указатель, чтобы определить, экземпляром какого класса является объект. Не все реализации виртуальных машин должны сохранять указатели типов данных объекта, другими словами, поиск метаданных объекта не обязательно проходит через сам объект.

    Кроме того, если это массив, в заголовке объекта также используется фрагмент данных, используемый для хранения длины массива, поскольку виртуальная машина может определить размер объекта Java с помощью информации метаданных обычных объектов Java, но размер массива не может быть определен из метаданных массива.Среди них предвзятые блокировки и облегченные блокировки добавляются после оптимизации synchronized в java6, которая будет представлена ​​позже.

  2. данные экземпляра

    Часть данных экземпляра — это эффективная информация, которую фактически хранит объект, то есть содержимое различных типов полей, которые мы определяем в программном коде, независимо от того, унаследовано ли оно от родительского класса или определено в подклассе, необходимо записать. На порядок хранения этой части влияет параметр стратегии выделения виртуальной машины (FieldsAllocationStyle) и порядок, в котором поля определены в исходном коде Java.

    Стратегия распределения по умолчанию для виртуальной машины HotSpot: длинные/двойные, целые, короткие/символы, байты/логические значения, oops (обычные указатели объектов).Из стратегии распределения видно, что поля одинаковой ширины всегда выделяются вместе. Когда это предварительное условие выполнено, переменные, определенные в родительском классе, появятся перед дочерним классом. Если значение параметра CompactFields равно true (значение по умолчанию — true), более узкие переменные в подклассе также могут быть вставлены в промежутки в переменной родительского класса.

  3. Выровнять отступы

    Третья часть заполнения выравнивания не обязательно существует и не имеет особого значения, она просто действует как заполнитель. Поскольку система автоматического управления памятью HotSpot VM требует, чтобы начальный адрес объекта был целым числом, кратным 8 байтам, иными словами, размер объекта должен быть целым числом, кратным 8 байтам. Заголовок объекта точно кратен 8 байтам (1 или 2 раза), поэтому, когда часть данных экземпляра объекта не выровнена, ее необходимо заполнить путем заполнения выравнивания.

Во-вторых, процесс создания

На уровне языка создание объектов обычно(исключения: клонирование, десериализация)Это просто новое ключевое слово, а в виртуальной машине что такое создание объектов (ограничено обычными объектами Java, исключая массивы и объекты класса и т. д.)?

Далее анализируется работа виртуальной машины при встрече с новой инструкцией:

Хранение объекта включает в себя три части памяти: стек методов (указатель хранения), область методов (хранение информации о классе, константы, статические переменные), куча (хранение данных экземпляра объекта). Среди них есть два способа реализации «ссылки на объект» на крайнем левом рисунке, как показано на правом рисунке ниже (два типа: 1. Реализуемый дескриптором; 2. Реализуемый прямым указателем;):




3. Примеры

В Hotspot JVM на 32-битной машине, во сколько раз больше размер объекта Integer?

int занимает 4 байта. Из приведенного выше анализа структура Integer может быть получена следующим образом:


Integer имеет только одно значение переменной-члена типа int, поэтому размер фактической части данных объекта составляет 4 байта, а затем 4 байта заполняются сзади для достижения 8-байтового выравнивания, поэтому можно сделать вывод, что размер объекта Integer составляет 16 байт.

Следовательно, мы можем сделать вывод, что размер объекта Integer в 4 раза больше размера нативного типа int.

Что касается структуры памяти объекта, следует отметить, что структура памяти массива немного отличается от структуры обычного объекта.Поскольку данные имеют поле длины, после заголовка объекта имеется поле длины типа int, которое занимает 4 байта Далее идут данные в массиве, а именно: