Это - мое понимание, что все экземпляры объектов.NET начинаются с 8-байтового 'объектного заголовка': синхронизирующий блок (4-байтовый указатель в таблицу SynchTableEntry), и дескриптор типа (4-байтовый указатель в таблицу метода типов).
Я не вижу это в VS 2010 RC (CLR 4.0) окна памяти отладчика.
Вот простой класс, который генерирует 16-байтовый экземпляр, меньше объектный заголовок.
class Program
{
short myInt = 2; // 4 bytes
long myLong = 3; // 8 bytes
string myString = "aString"; // 4 byte object reference
// 16 byte instance
static void Main(string[] args)
{
new Program();
return;
}
}
Дамп объекта SOS говорит мне, что общий размер объекта составляет 24 байта. Это имеет смысл. Мой 16-байтовый экземпляр плюс 8-байтовый объектный заголовок.
!DumpObj 0205b660 Name: Offset_Test.Program MethodTable: 000d383c EEClass: 000d13f8 Size: 24(0x18) bytes File: C:\Users\Bob\Desktop\Offset_Test\Offset_Test\bin\Debug\Offset_Test.exe Fields: MT Field Offset Type VT Attr Value Name 632020fc 4000001 10 System.Int16 1 instance 2 myInt 632050d8 4000002 4 System.Int64 1 instance 3 myLong 631fd2b8 4000003 c System.String 0 instance 0205b678 myString
Вот необработанная память:
0x0205B660 000d383c 00000003 00000000 0205b678 00000002 ...
И вот некоторые аннотации:
offset 0 000d383c ;TypeHandle (pointer to MethodTable), 4 bytes offset 4 00000003 00000000 ;myLong, 8 bytes offset 12 0205b678 ;myString, 4 byte reference to address of "myString" on GC Heap offset 16 00000002 ;myInt, 4 bytes
Мой объект начинает адрес 0x0205B660. Но я могу только объяснить 20 байтов из него, дескриптор типа и поля экземпляра. Нет никакого знака синхронизирующего указателя блока. О размере объекта сообщают как 24 байта, но отладчик показывает, что только занимает 20 байтов памяти.
Я читаю Развертку Во Внутренности Платформы.NET, чтобы Видеть, Как CLR Создает Объекты периода выполнения и ожидал первые 4 байта моего объекта быть обнуленным синхронизирующим указателем блока, как показано на рисунке 8 той статьи. Предоставленный, это - статья о CLR 1.1.
Я просто задаюсь вопросом, является ли различием между тем, что я вижу и о чем сообщает эта ранняя статья, изменение или в дисплее отладчика структуры объекта, или в способе, которым CLR размечает объекты в версиях позже, чем 1,1.
Так или иначе кто-либо может объяснить мои 4 недостающих байта?
Я считаю, что блок синхронизации находится «за» указателем объекта в памяти. Таким образом, ссылочная переменная указывает прямо на таблицу методов. Итак, для вашего объекта по адресу 0x0205B660 блок синхронизации будет по адресу 0x0205B65C.