类对象的内存分配
我在面试中被问过这个问题。 请帮我找到答案。
假设您有一个Employee类。 它有2个变量 – 1.字符串名称2. Int年龄
现在, Employee emp = new Employee();
现在提出的问题是:
- 对象emp存储在内存中,即堆栈或堆中,如何?
- 名称和年龄变量存储在内存中的位置如何?
- 这句话中的每个单词都做了什么,即员工做了什么……然后才知道……然后是新的..然后是员工..然后()..然后;
- 上述声明与Employee emp之间有什么区别; ? 告诉内存分配。?
请回复您的宝贵意见。
- 对象emp存储在内存中,即堆栈或堆中,如何?
问题是措辞不力。 emp
不是一个对象 ; emp
是一个包含对象引用的变量 。
那么让我们重新提出问题:
1(a)存储在内存中的
emp
引用的对象在哪里?
变量emp
引用的对象存储在长期存储中,也称为“堆”。
1(b)
emp
是变量,因此代表存储位置。 内存中的存储位置在哪里?
这个问题没有给出足够的信息。 变量emp
可以是静态字段,实例字段或局部变量。 (由于分号,它不能是forms参数。)如果是本地,它也可以是lambda的封闭外部变量,或迭代器块的本地或异步方法。 所有这些都会改变变量的存储是短期存储还是长期存储。 如果是短期存储,它可以在堆栈上,也可以是寄存器。
2存储在内存中的
name
和age
变量在哪里?
由于它们是类的字段,因此与这些变量关联的存储位置始终位于长期堆上。
因为name
是string
类型,所以它引用的东西 – 一个字符串 – 也在堆上。 (或者,变量可以为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 = ..然后是新的……然后是员工..然后()..然后;
创建一个名为emp
的Employee
类的新实例
4-上述声明与Employee emp有何区别; ? 告诉内存分配。?
Employee emp;
意味着只是声明, 而不是实例化 。 这意味着没有为对象分配内存,它将保持为null
。
对象emp存储在内存中,即堆栈或堆中,如何?
它是在堆上分配的,正如你所说Employee
是一个class
。 类在堆上分配。
name
和age
变量存储在内存中的位置如何?
这取决于您如何使用它们,并且可以在不同的框架实现之间变化。 一般来说,把它当作对象的记忆本身就好了。
这句话中的每个单词都做了什么,即员工做了什么……然后才知道……然后是新的..然后是员工..然后()..然后;
您为Employee
类型分配了nececssary内存,并将其分配给指针emp
。 指针emp
根据其使用方式被推入堆栈或堆栈 。
上述声明与Employee emp之间有什么区别; ? 告诉内存分配。?
Employee emp;
与编写Employee emp = default(Employee);
对于引用类型,default是null
,所以这等于写Employee emp = null;
。 所以在分配方面应该没有任何区别。
进一步阅读:
.NET中的C#堆(与)堆栈(ing):第一部分