类对象的内存分配

我在面试中被问过这个问题。 请帮我找到答案。

假设您有一个Employee类。 它有2个变量 – 1.字符串名称2. Int年龄

现在, Employee emp = new Employee();

现在提出的问题是:

  1. 对象emp存储在内存中,即堆栈或堆中,如何?
  2. 名称和年龄变量存储在内存中的位置如何?
  3. 这句话中的每个单词都做了什么,即员工做了什么……然后才知道……然后是新的..然后是员工..然后()..然后;
  4. 上述声明与Employee emp之间有什么区别; ? 告诉内存分配。?

请回复您的宝贵意见。

  1. 对象emp存储在内存中,即堆栈或堆中,如何?

问题是措辞不力。 emp不是一个对象 ; emp是一个包含对象引用变量

那么让我们重新提出问题:

1(a)存储在内存中的emp引用的对象在哪里?

变量emp引用的对象存储在长期存储中,也称为“堆”。

1(b) emp是变量,因此代表存储位置。 内存中的存储位置在哪里?

这个问题没有给出足够的信息。 变量emp可以是静态字段,实例字段或局部变量。 (由于分号,它不能是forms参数。)如果是本地,它也可以是lambda的封闭外部变量,或迭代器块的本地或异步方法。 所有这些都会改变变量的存储是短期存储还是长期存储。 如果是短期存储,它可以在堆栈上,也可以是寄存器。

2存储在内存中的nameage变量在哪里?

由于它们是类的字段,因此与这些变量关联的存储位置始终位于长期堆上。

因为namestring类型,所以它引用的东西 – 一个字符串 – 也在堆上。 (或者,变量可以为null,在这种情况下,它不会引用任何内容。)

3本声明中的每个单词都做了什么,即员工做了什么……然后再…然后新..然后雇员..然后()..然后;

这个问题的措辞非常糟糕。 首先,那些不是“文字”,那些是“代币”。 (和()两个令牌。)其次,完全不清楚问题的意思是“做”。 那么让我们问一个不同的问题:

3详细描述此声明在运行时执行时执行的操作。

我们不能说任何精确,因为问题中没有足够的信息。 问题是它是一个声明,所以它不是一个现场声明。 为简单起见,我们假设它不在迭代器块或异步方法中,并且本地不是任何匿名函数的外部变量。

  • 首先,为变量分配短期存储; 它可能会被注册; 如果没有,它将在堆栈中。 它被赋予一个空引用。

  • 其次,要求内存分配器为堆上的Employee实例生成空内存。 它这样做并产生对该内存的引用。

  • 第三,如果这是我们第一次看到Employee和Employee有一个静态构造函数,那么静态构造函数就会运行。

  • 第四,在静态ctor完成后,Employee的字段初始化程序运行。

  • 第五,Employee的基类构造函数运行。 这可能会导致其他静态构造函数执行。

  • 第六,Employee的构造函数体。

  • 第七,构造函数完成,并将对now-initialized对象的引用复制到其存储中。

所有这一切当然都假设一路走来都没有引发exception。

4上述声明与Employee emp;有何区别Employee emp; ? 告诉内存分配。

该问题没有足够的信息来提供准确的答案。 如果从未使用局部变量,则编译器可以自由地对其进行优化。 如果它没有对它进行优化,那么emp的存储emp短期池中分配,初始化为null,并且从未使用过。

你应该看到: Stack是一个实现细节 , 第一部分和第二部分作者:Eric Lippert

1 – 对象emp存储在内存中,即堆栈或堆中,如何?

堆上 ,因为它是一个引用类型,因为Employee是一个类。

2 – 名称和年龄变量存储在内存中的位置如何?

它们也存储在堆上。 虽然age是值类型,但值类型存储在存储容器引用的位置。

3 – 本声明中的每个单词都做了什么,即员工做了什么……然后是emp..then = ..然后是新的……然后是员工..然后()..然后;

创建一个名为empEmployee类的新实例

4-上述声明与Employee emp有何区别; ? 告诉内存分配。?

Employee emp; 意味着只是声明, 而不是实例化 。 这意味着没有为对象分配内存,它将保持为null

对象emp存储在内存中,即堆栈或堆中,如何?

它是在堆上分配的,正如你所说Employee是一个class 。 类在堆上分配。

nameage变量存储在内存中的位置如何?

这取决于您如何使用它们,并且可以在不同的框架实现之间变化。 一般来说,把它当作对象的记忆本身就好了。

这句话中的每个单词都做了什么,即员工做了什么……然后才知道……然后是新的..然后是员工..然后()..然后;

您为Employee类型分配了nececssary内存,并将其分配给指针emp 。 指针emp根据其使用方式被推入堆栈堆栈

上述声明与Employee emp之间有什么区别; ? 告诉内存分配。?

 Employee emp; 

与编写Employee emp = default(Employee); 对于引用类型,default是null ,所以这等于写Employee emp = null; 。 所以在分配方面应该没有任何区别。

进一步阅读:

.NET中的C#堆(与)堆栈(ing):第一部分