Как определить размер объекта, С#?
У меня есть следующий класс:
public class MyClass
{
public string Name { get; set; }
public int Age { get; set; }
public double Amount { get; set; }
}
Когда я пытаюсь выяснить размер этого класса в 64-битной системе с помощью WinDbg, я получаю размер 40
который я не могу понять, насколько я читал, MyClass должен иметь
8 bytes for SyncBlock
8 bytes for TypeHandle
8 bytes for string reference
4 bytes for Int32
8 bytes for double
= 36 bytes
У меня нет 10 репутации, поэтому я не могу опубликовать изображение.
Кто-нибудь знает, почему WinDbg показывает 4 дополнительных байта?
Ответы
Ответ 1
Я считаю, что то, что вы видите, - это эффект того, что нужно согласовать с 8-байтовыми границами в 64-битных строках (и 4 байтовых границах в 32-битных сборках). 40 - ближайший размеp >= 36, который находится на границе 8 байтов. Эти ссылки говорят о размере объекта:
Из памяти и строк (блог Jon Skeet)
Бенчмаркинг С# Структуры и размеры объектов
Сверлить внутри .NET Framework Internals, чтобы узнать, как среда CLR создает объекты времени выполнения
Сколько памяти занимает строка С#
Ответ 2
Это связано с тем, что типы заполнения подходят для границ адресов.
Это зависит от типов, которые вы используете, от времени выполнения и StructLayoutAttribute, используемых для типа.
если вы посмотрите на Int32
с отражателем, вы увидите:
StructLayout(LayoutKind.Sequential)
Этот означает, что он может быть несмежным:
Члены объекта выкладываются последовательно, в порядке которые они появляются при экспорте в неуправляемую память. Члены выложенный в соответствии с упаковкой, указанной в StructLayoutAttribute.Pack и может быть несмежным.
Значение StructLayoutAttribute.Pack не установлено, это означает, что оно равно 0 (значение по умолчанию)
Значение 0 указывает, что выравнивание упаковки установлено по умолчанию для текущей платформы. Это обычно 4 байта для x86 и 8байт для x64, но он оптимизирован CLR в базе системы, и это значение может меняться
Вы можете видеть это с помощью:
#pragma pack(show)