Компоновка примитивного массива 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, и второй связан с внутренними данными, которые необходимо скрыть.

Я также знаю об этом, но это кажется не связанным, так как означает < em>внутреннее заполнение.

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


person Eugene    schedule 24.05.2018    source источник
comment
Разве выравнивание не всегда является степенью двойки? В обоих случаях размер больше 32 байт, поэтому вам понадобится увеличить до 64. Не уверен, что это применимо здесь, хотя...   -  person Jorn Vernee    schedule 24.05.2018
comment
FWIW, я получил размер экземпляра 56 байтов, из которых 4 потеряны из-за следующего выравнивания объекта в 32 битах и ​​0 потеряны в 64 битах.   -  person Michael    schedule 24.05.2018
comment
@Michael указывает на то, что это не должно быть степенью двойки, верно? Я работал над примером, чтобы доказать это JornVernee   -  person Eugene    schedule 24.05.2018
comment
Вы знаете, что что-то не так, если вы не видите длину массива где-то в заголовке объекта…   -  person Holger    schedule 24.05.2018
comment
@Holger :) о боже! даже не заметил, что за идиот... спасибо!   -  person Eugene    schedule 25.05.2018


Ответы (1)


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

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

См. ClassLayout.java

person apangin    schedule 24.05.2018
comment
еще один небольшой вопрос: не должен ли явный Layouter дополнять 8-байтовое выравнивание? - person Eugene; 25.05.2018
comment
@ Юджин, я не понимаю, что ты имеешь в виду. VM сообщает, что этот объект в настоящее время занимает 64 байта в куче, и Layouter пытается объяснить, откуда эти 64 байта. Когда вы выбираете Layouter из другой конфигурации VM, вы определенно получите запутанные результаты, поскольку он не может разумно объяснить лишние байты. Я не знаю, почему в JOL возможно создание произвольного Layouter - возможно, это ошибка API. - person apangin; 25.05.2018
comment
Я вообще не считаю это ошибкой; что, если я хочу найти макет объекта, не имея доступа к определенной платформе? Нравится x86_32? На самом деле я имел в виду, что явный макет вычисляет размер как 52 bytes, я действительно ожидал сказать позже: 4 bytes padding - размер экземпляра = 56 bytes вместо дать мне реальный размер. Я не спрашивал реальный размер платформы для начала. Или, другими словами: каким будет результат для реального бита x86_32 в первом примере? - person Eugene; 25.05.2018
comment
@Юджин Хорошо. Что я вижу, так это то, что ClassLayout берет реальный размер экземпляра, вычисленного для текущей запущенной виртуальной машины, не принимая во внимание модель данных данного компоновщика. Во всяком случае, мне кажется, что это несоответствие. Предлагаю открыть вопрос против JOL. - person apangin; 25.05.2018
comment
я изначально хотел, так что спасибо за подтверждение этого - person Eugene; 25.05.2018