2011-05-10 95 views

回答

5
void M() 
{ 
    Artist a = new Artist(); 
} 

当该方法被调用时,一个新的堆栈帧被扩展,则执行之前该方法的第一个语句,如绪论 CLR有一些准备代码。在此期间,CLR会加载该方法中使用的所有类型。在这个例子中,类型Artist将被加载到堆中。但是类型也可能已经存在,因为在调用M()之前使用了该类型。然后我们来看第一个表达式,一个new语句,它调用该类的构造函数。如果你看看它产生的CIL,你会看到类似newobj blabla的东西。这里在堆上分配一块内存用于存储实例。块的大小取决于类的细节,因为块需要保存实例的所有数据。通常,块由通过:

Type pointer + Sync root + Instance data 

型指针指向其上堆(在绪论加载)类型。同步根是锁定和同步的记录。实例数据存储实例的成员数据。

+0

仅供参考,答案很清楚。但是存储值类型的类型对象在哪里,值类型对象有:类型指针+同步根目录+实例数据额外字段? – Spirit 2016-02-03 18:35:39

2

CLR在您的对象实例中存储了几位信息。其中之一是指向对象类型的指针。

0

在第一次使用类之前,dotnet运行时会在堆上创建一个对象,该对象存储有关要使用的类的所有信息。这包括静态字段,一个指向类可用方法的方法表,一个类型对象指针(一秒钟更多)和一个同步块(用于锁定对象)。

所有对象都有一个类型对象指针,它指向一个存储有关类的信息的对象。因此,例如,如果您有一个Person对象,它将有一个类型对象指针,指向堆中存储关于person的所有信息的对象。这个人类型对象也有一个类型对象指针,它指向System.Type的一个对象,因为它的类型是System.Type(它是一个存储关于对象类型信息的对象)。

当然System.Type,作为堆上的对象也有一个类型对象指针,它指向它是什么类型的信息。正如你可能猜到的那样 - 它指向自身,因为System.Type对象是一个System.Type对象。

在对象上调用GetType()时,它只返回存储在特定对象类型对象指针中的地址。