Понимание размера объекта CLR между 32 битом VS 64 бита

StackOverflow https://stackoverflow.com/questions/3815227

  •  26-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь понять разницу размеров объекта между 32-битными и 64-битными процессорами. Скажем, у меня есть простой класс

class MyClass   
{  
    int x;  
    int y;  
}  

Так что на 32-битной машине целое число составляет 4 байта. Если я добавлю синхронизацию в него (еще один 4 байта), размер объекта будет 12 байт. Почему он показывает 16 байтов?

0: 000>! Do 0x029d8b98 Имя: ConsoSeaPlapation1.program + MyClass Methenttable: 000E33B0 EECLASS: 000E149C Размер: 16 (0x10) Байты (C:  Mytemp  ConsoleaPlapation1  ConsoSolaP1  bin  x86  debug  consoxication1.exe) Поля: MT Тип смещения поля VT attr Значение значения 71972D70 4000003 4 System.int32 1 экземпляр 0 x 71972D70 4000004 8 System.int32 1 экземпляр 0 y

На 64-битной машине целое число все еще 4 байта. Единственное изменилось, что синхронизация будет 8 байт (в качестве указателей 8 байтов на 64-битных машинах). Это означает, что размер объекта будет 16 байт. Почему это показывает 24 байта?

0: 000>! Do 0x00000000028f3c90 name: consoleaPlain1.program + myclass messageTable: 000007FF00043AF8 EECLASS: 000007FF00182408 Размер: 000007FF00182408 Размер: 24 (0x18) Байты (C:  MyTemp  ConsoleaPlapion1  ConsoleaP1.exe1  bin  debug  consoleaP1.exe) Поля: MT Тип vt attr Значение значения 000007fef4edd988 4000003 8 System.int32 1 экземпляр 0 x 000007fef4edd998 4000004 c system.32 1 экземпляр 0 y
Это было полезно?

Решение

CLR может свободно выкладывать объекты в память, когда оно видит в форме. Это деталь реализации. Вы не должны полагаться на любой конкретный макет.

Разница, которую вы видите, связано с отсутствующим полем Typehandle, которое также является частью заголовка объекта CLR. Кроме того, поля могут быть выровнены на границы байтов.


От Расширенная отладка .NET - внутренняя структура объекта CLR:

Внутренняя структура CLR объекта:

DWORD: SyncBlock] [DWORD: Указатель методирования] [DWORD: указатель типа ссылки] ... [Значение поля типа значения] ...

Заголовок объекта: DWORD: SyncBlock
Указатель объекта: DWORD: Указатель методика] [DWORD: указатель типа ссылки] ... [Значение поля типа Value] ...

Каждый объект предшествует OBJHEDER (при отрицательном смещении). У Objheader есть индекс для синхронизации.


Таким образом, ваш объект, скорее всего, выложен так:

x86.: (выровнен до 8 байтов)

 Syncblk typehandle xy --------------, ------------- | ------------------------- ---- |. 8 16.

x64.: (выровнен до 8 байтов)

 Syncblk Typehandle XY ---------------------------- | ------------------------- ---- | --------------, ------------- | 8 16 24.

Смотрите также: Сверлить в .NET Framework Internals, чтобы увидеть, как CLR создает объекты времени выполнения

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

Блок синхронизации сидит при отрицательном смещении от указателя объекта. Первое поле на смещении 0 - указатель таблицы метода, 8 байтов на X64. Так что на X86 это SB + Mt + x + y = 4 + 4 + 4 + 4 = 16 байтов. Индекс блока синхронизации по-прежнему 4 байта в X64. Но заголовок объекта также участвует в сборной мусоре, выступая в качестве узла в связанном списке после его освобождения. Для этого требуется задняя и прямая указатель, каждый 8 байт в X64, что требует 8 байтов до указателя объекта. 8 + 8 + 4 + 4 = 24 байта.

Объекты имеют некоторые накладные расходы за пределы переменных элементов. В 32-разрядных реализациях .NET, накладные расходы на выделение, кажется, 12 байт. Как я помню, это 16 байтов в 64-битной среде выполнения.

Кроме того, распределение объектов выровнено на следующей 8 байт-границе.

Мне кажется, любой объект должен иметь какой-то указатель на свой класс. Это объясняется для ваших дополнительных 4 или 8 байтов.

Макет объекта - это действительно реализация, хотя. Если вы заботитесь о макете, есть атрибуты, предназначенные для явных сообщений .NET, где и как вы хотите, чтобы участники расположены. Проверить Structlayoutattribute..

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top