首页 > 解决方案 > 这个对象的内存是什么样子的?

问题描述

我想知道这个类(它的对象)的内存布局如何:

class MyClass
{
    string myString;

    int myInt;

    public MyClass(string str, int i)
    {
        myString = str;
        myInt = i;
    }
}

MyClass obj = new MyClass("hello", 42);

谁能想象一下?

更新:

根据 Olivier Rogier 的回答以及 ckuri 和 Jon Skeet 的评论,我试图提出一个高级图表,深受ckuri提到的开发博客文章的影响。

所以据我了解:

  1. obj(8 字节引用)指向包括元数据的对象(实际上不是它的开头,但为了简单起见我们忽略它)。

  2. 在这个地方myInt存储和myString引用值(这是对真实字符串值的引用)

在此处输入图像描述

我不想进入最后的细节,但我仍然很好奇:

  1. 如果obj.myString应该被访问,是否有必要进行两次“查找”,例如首先查找obj,然后跟随它并查找,myString或者是否有类似全局地址表的东西obj.myString直接存储地址?

  2. 存储的参考值在哪里obj?它是program对象块的一部分,就像myString是对象块的一部分obj吗?(假设obj是在一个实例中创建的program

标签: c#memory

解决方案


在这个地方存储了 myInt 和 myString 引用值(这是对真实字符串值的引用)

让我们确保你不会在这里走坏路。

首先,我不清楚为什么与源代码相比,您对图中的整数和字符串进行了重新排序。它是实现定义的字符串和整数如何打包,以什么顺序,以及是否有任何填充字节。如果您关心这些细节,请提出更明确的问题。

其次,不清楚“真正的字符串值”是什么意思。字符串是引用类型。字符串的真正值是引用字符串内容的值位于引用的位置。

如果要访问 obj.myString,是否需要两次“查找”,例如首先查找 obj,然后跟随它并查找 myString

我假设“查找”是指取消引用

例如,如果我们有:

var obj = whatever;
char c = obj.myString[1];

那么是的,我们有两个取消引用。对 get的.取消引用,这是一个引用。获取. _ _objmyString[1]myStringchar

obj 的引用值存放在哪里?

obj是一个变量。变量是一个存储位置。该存储位置可以位于多个位置:

  • 如果obj是短暂的,或者更好的是,短暂的,那么它可以注册或放入短期池中。(通常称为堆栈,但在我看来,从语义方面考虑短期池是一个更好的习惯,即寿命不超过激活的存储。堆栈是一个实现细节。)

  • 如果obj不知道是短期的,那么它将进入长期池,也称为托管堆。


推荐阅读