Не видит блок синхронизации в макете объекта - PullRequest
5 голосов
/ 12 апреля 2010

Насколько я понимаю, все экземпляры объекта .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 Framework, чтобы увидеть, как CLR создает объекты времени выполнения , и ожидал, что первые 4 байта моего объекта будут нулевым указателем блока синхронизации, как показано на рисунке 8 этой статьи. Конечно, это статья о CLR 1.1.

Мне просто интересно, если разница между тем, что я вижу, и тем, о чем говорится в этой ранней статье, заключается в изменении либо отображения отладчика макета объекта, либо способа, которым CLR выкладывает объекты в версиях более поздних, чем 1.1.

В любом случае, кто-нибудь может объяснить мои 4 пропущенных байта?

1 Ответ

8 голосов
/ 12 апреля 2010

Я считаю, что блок синхронизации находится «позади» указателя объекта в памяти. Таким образом, ссылочная переменная указывает непосредственно на таблицу методов. Итак, для вашего объекта по адресу 0x0205B660 блок синхронизации будет по адресу 0x0205B65C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...