Макет примитивного массива Java в памяти

Вот два образца, на которых я хотел бы основывать свой вопрос (при условии, что у вас здесь JOL):

Layouter layout32Bits =  new HotSpotLayouter(new X86_32_DataModel());
Layouter layout64BitsComp = new HotSpotLayouter(new X86_64_COOPS_DataModel());

И пример, использующий это:

int [] ints = new int[10];  

System.out.println(ClassLayout.parseInstance(ints, layout32Bits).toPrintable());
System.out.println(ClassLayout.parseInstance(ints, layout64BitsComp).toPrintable());

А вот два выхода:

  [I object internals:
  OFFSET  SIZE   TYPE DESCRIPTION             VALUE
  0     4        (object header)     09 00 00 00 (00001001 00000000 00000000 00000000) (9)
  4     4        (object header)     00 00 00 00 (00000000 00000000 00000000 00000000) (0)
  8     4        (object header)     10 1b 0c 1a (00010000 00011011 00001100 00011010) (437000976)
 12    40    int [I.<elements>            N/A
 52    12        (loss due to the next object alignment)
 Instance size: 64 bytes
 Space losses: 0 bytes internal + 12 bytes external = 12 bytes total

  [I object internals:
  OFFSET  SIZE   TYPE DESCRIPTION             VALUE
  0     4        (object header)     09 00 00 00 (00001001 00000000 00000000 00000000) (9)
  4     4        (object header)     00 00 00 00 (00000000 00000000 00000000 00000000) (0)
  8     4        (object header)     10 1b 0c 1a (00010000 00011011 00001100 00011010) (437000976)
 12     4        (object header)     01 00 00 00 (00000001 00000000 00000000 00000000) (1)
 16    40    int [I.<elements>            N/A
 56     8        (loss due to the next object alignment)
 Instance size: 64 bytes
 Space losses: 0 bytes internal + 8 bytes external = 8 bytes total

В основном я понимаю вывод, но я не знаю, что это:

12 bytes external and 8 bytes external

В общем, объекты выровнены по 8 bytes, так зачем добавлять заполнение более, чем необходимо?

Я знаю несколько странных вещей: первый связан с API, который использует JOL. и второй имеет отношение к внутренним данным, которые необходимо скрыть.

Я также знаю о это, но, похоже, это не связано с внутренняя обивка.

Может кто-нибудь пролить свет на это?

Разве выравнивание всегда не в степени 2? В обоих случаях размер больше 32 байтов, поэтому вам нужно дополнить его до 64. Не уверен, что здесь это применимо ...
Jorn Vernee 24.05.2018 14:40

FWIW, я получил размер экземпляра 56 байтов, из которых 4 потеряно из-за следующего выравнивания объекта в 32 битах и ​​0 потеряно в 64 битах.

Michael 24.05.2018 14:55

@Michael указывает на то, что нет должен быть степенью двойки, верно? Я работал над примером, чтобы доказать это Йорну Верни.

Eugene 24.05.2018 14:56

Вы знаете, что что-то не так, если где-то в заголовке объекта не видите длину массива ...

Holger 24.05.2018 18:29

@Holger :) Боже мой! даже не заметил, какой идиот ... спасибо!

Eugene 25.05.2018 10:12
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
9
5
850
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Instance size: 64 bytes рассчитан для текущей конфигурации виртуальной машины, но вы явно указываете другой (несовместимый) Layouter.

Разница между фактическим размером (рассчитанным с помощью Instrumentation.getObjectSize) и ожидаемым размером (рассчитанным Layouter) будет рассматриваться как loss due to the next object alignment.

См. ClassLayout.java

один второстепенный вопрос, не должен ли явный Layouter по-прежнему дополнять выравнивание до 8 байтов?

Eugene 25.05.2018 10:16

@ Евгений Я не понимаю, что вы имеете в виду. VM сообщает, что «этот объект в настоящее время занимает 64 байта в куче», и Layouter пытается объяснить, откуда эти 64 байта. Когда вы выбираете Layouter из другой конфигурации виртуальной машины, вы определенно получите запутанные результаты, поскольку он не может разумно объяснить дополнительные байты. Я не знаю, почему в JOL возможно создание произвольного Layouter - вероятно, это ошибка API.

apangin 25.05.2018 11:24

Я вообще не считаю это ошибкой; что, если я хочу найти макет объекта, не имея доступа к определенной платформе? Нравится x86_32? На самом деле я имел в виду, что явный макет вычисляет размер как 52 bytes, я действительно ожидал, что позже скажу: 4 bytes padding - instance size = 56 bytesвместо, чтобы дать мне размер настоящий. Для начала я не спрашивал реальный размер платформы. Или иначе: каков будет результат для бита настоящий x86_32 для первого примера?

Eugene 25.05.2018 11:30

@ Евгений Хорошо. Я вижу, что ClassLayout принимает реальный размер экземпляра, вычисленного для текущей запущенной виртуальной машины, игнорируя модель данных данного макета. Мне все равно кажется несоответствие. Предлагаю открыть вопрос против JOL.

apangin 25.05.2018 11:51

я изначально хотел, так что спасибо, что подтвердили это

Eugene 25.05.2018 11:55

Другие вопросы по теме