没有在对象布局中看到同步块

时间:2010-04-11 21:11:35

标签: .net clr

据我所知,所有.NET对象实例都以一个8字节的“对象头”开头:一个同步块(指向SynchTableEntry表的4字节指针)和一个类型句柄(指向类型方法表的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个字节的内存。

我正在阅读Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects,并期望我的对象的前4个字节是一个归零的同步块指针,如该文章的图8所示。当然,这是一篇关于CLR 1.1的文章。

我只是想知道我所看到的内容和早期文章报告的内容之间的区别是调试器的对象布局显示的更改,还是CLR在1.1之后的版本中布局对象的方式。

无论如何,任何人都能解释我丢失的4个字节吗?

1 个答案:

答案 0 :(得分:8)

我相信同步块在内存中的对象指针“后面”。这样,引用变量直接指向方法表。因此,对于地址为0x0205B660的对象,同步块将位于地址0x0205B65C。