Обзор
Объект можно разделить на два случая в соответствии с различными ситуациями.Когда объект не является объектом-массивом, заголовок объекта, данные экземпляра и выравнивание заполняются в трех частях памяти, а объект-массив имеет еще одну функцию в заголовок объекта для части, описывающей длину объекта массива
заголовок объекта
Заголовок объекта разделен на две части, первая часть называется **"Mark Word", вторая часть используется для получения типа объектаУказатель типа**, если это объект массива, он также включает данные, записывающие длину массива.
В разных операционных системах память, занимаемая этими областями, также отличается, в 32-битной системе MarkWord занимает 32 бита пространства (то есть 4 байта). Указатель типа и данные длины массива совместно занимают 32-битное пространство.
В 64-разрядной операционной системе MarkWord занимает 64 бита пространства, а указатель типа составляет 64 бита (8 байтов) без включения сжатия указателя (CompressedOOPs), но только 32 бита (4 байта), когда включено сжатие указателя.
Mark Word
Эта часть хранитданные времени выполнения самого объекта, структура данных этого фрагмента контента не фиксирована, он будет повторно использовать собственное пространство для хранения в соответствии с состоянием объекта,
Вот фрагмент из файла markOop.hpp, который представляет следующие пять состояний объекта:
бит флага | Флаг блокировки смещения | условие |
---|---|---|
01 | 0 | нет замка |
01 | 1 | Блокировка смещения |
00 | никто | Легкий замок |
10 | никто | тяжелый замок |
11 | никто | GC Mark |
Давайте посмотрим на структуру MarkWord дальше:
Здесь мы видим, что структура состояний lock-free иbiasedlock определяется только во время инициализации (верхняя часть — это структура без сжатия COOPs-указателя, а нижняя часть — структура с включенным сжатием указателя),
Когда он находится в легковесной или тяжеловесной блокировке, записанный указатель объекта, согласно описанию JVM, считает, что в это время указатель по-прежнему 64-битный, а младшие два бита считаются равными 0; когда он находится в смещенная блокировка, запись для получения смещенной блокировки Указатель потока, который также является 64-битным;
Мы не будем расширять здесь больше контента.По отзывам, я напишу отдельную статью в последующем параллельном программировании, чтобы рассказать об эволюции блокировок.
указатель типа
Иногда это используется, чтобы определить, принадлежит ли объекткакой экземпляр класса, а когда это нецелесообразно, это должно быть сделано в соответствии с выбором различных виртуальных машин для алгоритма реализации позиционирования объекта (например, JVM HotSpot использует этот тип указателя для получения данных типа объекта)
данные экземпляра
Данные экземпляра — это эффективная информация, которую фактически хранит объект, а также различные типы данных, определенные в программном коде.содержимое поля, содержимое поля здесь включает не только поля текущего класса, но и поля, определенные в его родительском классе.
Правила хранения в этой части следуют порядку определения параметров и полей стратегии выделения виртуальных машин в исходном коде Java. pointer, Ordinary Object Pointers) тоже можно понимать как ссылку, о сжатии указателя мы поговорим в следующем разделе.
Здесь следует отметить, что переменные, определенные в родительском классе, появятся перед подклассом, но мы можем вставить меньшие переменные в подклассе в промежутки между большими переменными в родительском классе, установив для параметра CompactFileds значение true.
Выровнять отступы
Эта часть содержимого не обязательно должна существовать, поскольку JVM Hot Spot указываетРазмер объекта должен быть целым числом, кратным 8 байтам., в C/C++ аналогичная функция называетсявыравнивание памяти, пространство памяти разделено по байтам.Теоретически кажется, что доступ к любому типу переменной может начинаться с любого адреса, но реальная ситуация такова, что при обращении к определенному типу переменной, к ней часто обращаются по определенному адреса памяти, для чего требуются различные типы данных, которые располагаются в пространстве по определенным правилам, а не последовательно друг за другом, что является выравниванием.
Выравнивание памяти следует двум правилам:
Предполагая, что начальный адрес первого члена равен 0, начальный адрес (startpos) каждого члена должен быть целым числом, кратным пространству, занимаемому его типом данных.
Окончательный размер структуры должен быть целым числом, кратным размеру наибольшего члена ее членов (членов базового типа данных).
Нетрудно понять, почему в JVM оговаривается, что размер объекта должен быть целым числом, кратным 8 байтам, ведь в 64-битной системе (без включения сжатия указателей) в объекте много типов данных, занимающих 8 байт. Но в то же время есть и некоторые 4-байтные типы данных, в это время наш Padding играет роль в дополнении той части, которая меньше 8 байт и составляет целое число, кратное 8.