【问题标题】:Where the 'Type' of a reference value is stored in memory?参考值的“类型”存储在内存中的什么位置?
【发布时间】:2011-05-10 07:08:16
【问题描述】:

由于引用值作为数据存储在堆中;任何引用值的类型信息都存放在哪里?

如果有几个 Artist 类的实例;当它们存储在堆中时,.Net 如何将这些内存块标记为 Artist 类型?

谢谢!

【问题讨论】:

    标签: c# .net vb.net memory reference


    【解决方案1】:
    void M()
    {
       Artist a = new Artist();
    }
    

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

    Type pointer + Sync root + Instance data
    

    类型指针指向它在堆上的类型(加载在prolegomenon中)。同步根是用于锁定和同步的记录。实例数据存储实例的成员数据。

    【讨论】:

    • 对于参考类型,答案很明确。但是存储值类型的类型对象在哪里,值类型对象有没有:类型指针+同步根+实例数据额外字段?
    【解决方案2】:

    CLR 将一些信息与对象实例中的数据一起存储。其中之一是指向对象类型的指针。

    【讨论】:

      【解决方案3】:

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

      所有对象都有一个类型对象指针,它指向一个存储类信息的对象。

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

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

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

      【讨论】:

        猜你喜欢
        • 2011-02-21
        • 2017-07-17
        • 2013-04-24
        • 2023-03-07
        • 2021-10-17
        • 2010-11-20
        • 2021-01-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多