Фактический размер объекта зависит от реализации, и даже не требуется, чтобы необходимый размер объекта оставался неизменным в течение всего срока его жизни.
На wiki.openjdk.java есть статья.net заявив:
Расположение заголовка объекта
Заголовок объекта состоит из слова метки собственного размера, слова класса, слова длиной 32 бита (если объектявляется массивом), 32-разрядный пробел (если требуется правилами выравнивания), а затем ноль или более полей экземпляров, элементов массива или полей метаданных.(Интересные мелочи: метаобъекты Klass содержат таблицу V ++ сразу после слова klass.)
Поле пробела, если оно существует, часто доступно для хранения полей экземпляра.
Если UseCompressedOops имеет значение false (и всегда в системах ILP32), знак и класс являются родными машинными словами.Для массивов разрыв всегда присутствует в системах LP64 и только в массивах с 64-битными элементами в системах ILP32.
Если UseCompressedOops имеет значение true, класс равен 32 битам.Номера для массивов имеют поле пропуска сразу после класса, в то время как массивы сохраняют поле длины сразу после класса.
Вы вычисляете «заголовок + свойства + ссылка» для размера объекта неверно.Во-первых, ссылки на объект не являются частью размера объекта референта.Может быть произвольное количество ссылок на один и тот же объект, но эти ссылки вообще не должны быть в памяти кучи или в ОЗУ, поскольку оптимизированный код может обращаться к объекту исключительно через регистры ЦП.
Кроме того, как указывалось в приведенной выше цитате, существуют правила выравнивания, которые делают вычисление памяти, требуемой для полей, нетривиальным.В заголовке может быть пробел, который можно использовать для хранения полей экземпляра, если в него входят поля типа, подходящего для него.Хотя поля одного и того же класса могут быть расположены так, чтобы минимизировать заполнение, подкласс должен соответствовать макету суперкласса, потенциально добавляя к нему больше полей, и может заполнять пробелы только в том случае, если у него есть поля подходящих типов, в противном случаеможет быть еще больше пробелов из-за иерархии классов.
Для массивов вы можете извлечь из процитированной статьи, что 32-битное представление HotSpot использует заголовок из 12 байтов, если тип не равен long[]
или * 1024.*, в этом случае это будет 16 байтов.
Для 64-битной реализации опция UseCompressedOops
(которая включена по умолчанию) позволяет комбинировать слово 64-битной метки с 32-битным классом иДлина 32 бита, до заголовка 16 байтов.Только если UseCompressedOops
выключен, заголовок будет 24 байта.