当我们实例化类/结构 Student 时,将在堆栈和堆中分配多少内存?
我猜 id = 4 字节引用(32 位机器)和名称 = 4 字节引用和 facultyAdvisor = 4 字节引用。所以堆栈中总共有 12 个字节,实际大小将在堆中。此堆大小可能会有所不同,具体取决于我们分配给使用对象 obj(Student obj = new Student()) 的字段(id、名称、facultyAdvisor)的值
对于struct也是一样吧?
public class Student { int id; string name; Professor facultyAdvisor; }
public struct Student { int id; string name; Professor facultyAdvisor; }
最佳答案
首先注意 stack and the heap are implementation details ... 对象的大小也是如此。但是在当前的实现中,当 Student
是一个类时,fields 的所有数据都在堆上。有一个对象开销以及字段占用的内存,但所有这些都将在堆上。
如果您保留对新实例的引用,并且将其保留在未捕获的局部变量中,而不是在迭代器 block 或异步方法中,则该引用将在堆栈上(在当前的实现中)所以在 32 位 CLR 上它将是 4 个字节。
当 Student
是一个结构时,情况会有所不同:
- 数据的位置(堆栈或堆)取决于值的使用方式 - 例如,如果它存储在类的实例变量中,它将与其余数据一起在堆上;如果它在局部变量中(同样,未捕获且不在迭代器 block 或异步方法中)那么它将在堆栈上
- 你不是在创建一个单独的对象,只是一个值,所以没有额外的开销——它真的只需要 12 个字节(假设
Professor
是引用类型)
我有几篇文章/帖子您可能会觉得有用:
- Memory and object overheads (特别是字符串,但也包括其他类型)
- What goes where - 堆栈和堆,再次记住这是一个实现细节
编辑:解决 Professor
问题,假设 Professor
是一个类 - 除非显式创建 Professor
对象,否则 中的引用>Student
将简单地为空。创建一个新的 Student
不会自动创建一个新的 Professor
只是因为有一个该类型的字段。对 Professor
的引用只是 Student
数据的一部分 - 它存在于 id
存在的任何地方 - 所以如果 Student
是一个类,那么引用只存在于堆上,如果 Student
是一个结构,那么它取决于创建 Student
值的位置,如上所列。
关于c# - 对象创建时的内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6771522/