当我们实例化class / struct Student时,它将在堆栈和堆中分配多少内存?
我猜id = 4字节引用(32位机器)和name = 4字节引用和facultyAdvisor = 4字节引用。所以堆栈中总共12个字节,实际大小将在堆中。这个堆大小可能会有所不同取决于我们分配给使用对象obj的字段(id,name,facultyAdvisor)的值(Student obj = new Student())
结构也一样吗?
public class Student { int id; string name; Professor facultyAdvisor; }
public struct Student { int id; string name; Professor facultyAdvisor; }
答案 0 :(得分:5)
首先请注意stack and the heap are implementation details ...与对象的大小一样。但是在当前的实现中,Student
中字段的所有数据都在堆上。有一个对象开销以及为字段占用的内存,但所有这些都将在堆上。
如果要将引用保留到新实例中,并且将它保存在未捕获的局部变量中,而不是在迭代器块或异步方法中,则该引用将位于堆栈上(在当前的实现中)所以它在32位CLR上将是4个字节。
当Student
是一个结构时,事情会有所改变:
Professor
是一种参考类型)我有几篇您认为有用的文章/帖子:
编辑:解决Professor
问题,假设Professor
是一个类 - 除非明确创建Professor
对象,否则Student
中的引用将为空。创建新的Student
而不是会自动创建一个新的Professor
,因为有一个该类型的字段。对Professor
的引用只是Student
数据的一部分 - 它存在于id
所在的任何地方 - 所以如果Student
是一个类,那么引用只存在于堆,如果Student
是一个结构,那么它取决于创建Student
值的位置,如上所列。
答案 1 :(得分:1)
假设32位CLR(64位CLR上的引用将是64位)并且仅考虑学生的堆分配
班级学生{}班教授{}
班级学生{} struct教授{}
struct Student {}类教授{}
struct Student {} struct Professor {}
答案 2 :(得分:0)
您可以使用GC.GetTotalMemory(true)
调用来测量实例化之前和之后的内存消耗,以测量堆分配