由于参考值作为数据存储在堆中;哪里存储了任何参考值的类型信息?
如果有几个类艺术家的实例;当它们存储在堆中时,.Net如何将这些内存块标记为Artist的类型?
谢谢!
答案 0 :(得分:5)
void M()
{
Artist a = new Artist();
}
当调用该方法时,会扩展一个新的堆栈帧,CLR在执行该方法的第一个语句之前会有一些准备代码,就像 prolegomenon 一样。在此期间,CLR加载方法中使用的所有类型。在此示例中,Artist
的类型将加载到堆。但是类型也可能已存在,因为在调用M()
之前使用了类型。然后我们来到第一个表达式,一个new
语句,它调用类的构造函数。如果您查看它生成的CIL,您会看到类似newobj
blabla的内容。这里堆上的内存块被分配用于存储实例。块的大小取决于类的详细信息,因为块需要保存实例的所有数据。通常该块由以下部分组成:
Type pointer + Sync root + Instance data
类型指针指向堆上的类型(加载在 prolegomenon 中)。同步根是锁定和同步的记录。实例数据存储成员的实例数据。
答案 1 :(得分:2)
CLR在对象实例中存储了一些信息和数据。其中一个是指向对象类型的指针。
答案 2 :(得分:0)
在第一次使用类之前,dotnet运行时在堆上创建一个对象,该对象存储有关要使用的类的所有信息。这包括静态字段,指向类可用方法的方法表,类型对象指针(在一秒钟内更多)和同步块(用于锁定对象)。
所有对象都有一个类型对象指针,指向存储有关该类信息的对象。
因此,例如,如果你有一个Person对象,它将有一个类型对象指针,指向堆上的一个对象,它存储有关person的所有信息。此人类对象还将具有一个类型对象指针,该指针指向System.Type的对象,因为它的类型是System.Type(它是一个存储有关对象类型的信息的对象)。
当然,作为堆上对象的System.Type也有一个类型对象指针,它指向它是什么类型的信息。正如您可能已经猜到的那样 - 它指向自身,因为System.Type对象是System.Type对象。
当您在对象上调用GetType()时,它只返回存储在特定对象类型对象指针中的地址。