对象创建的内存分配

时间:2011-07-21 05:12:58

标签: c#

当我们实例化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; }

3 个答案:

答案 0 :(得分:5)

首先请注意stack and the heap are implementation details ...与对象的大小一样。但是在当前的实现中,Student字段的所有数据都在堆上。有一个对象开销以及为字段占用的内存,但所有这些都将在堆上。

如果要将引用保留到新实例中,并且将它保存在未捕获的局部变量中,而不是在迭代器块或异步方法中,则该引用将位于堆栈上(在当前的实现中)所以它在32位CLR上将是4个字节。

Student是一个结构时,事情会有所改变:

  • 数据(堆栈或堆)的位置取决于值的使用方式 - 如果它存储在类的实例变量中,例如,它将与其余数据一起存在于堆中;如果它在局部变量中(同样,未捕获而不是在迭代器块或异步方法中)那么它将在堆栈中
  • 您没有创建单独的对象,只是,因此没有额外的开销 - 它实际上只需要12个字节(假设为Professor是一种参考类型)

我有几篇您认为有用的文章/帖子:

编辑:解决Professor问题,假设Professor是一个类 - 除非明确创建Professor对象,否则Student中的引用将为空。创建新的Student 而不是会自动创建一个新的Professor,因为有一个该类型的字段。对Professor的引用只是Student数据的一部分 - 它存在于id所在的任何地方 - 所以如果Student是一个类,那么引用只存在于堆,如果Student是一个结构,那么它取决于创建Student值的位置,如上所列。

答案 1 :(得分:1)

假设32位CLR(64位CLR上的引用将是64位)并且仅考虑学生的堆分配

班级学生{}班教授{}

  • 堆叠:4个字节
  • 堆:4个字节(int)+ 4个字节(教授参考)+ 4个字节(字符串参考)+ 12个字节(对象标题)= 24个字节

班级学生{} struct教授{}

  • 堆叠:4个字节
  • 堆:4个字节(整数)+处理器大小+4个字节(字符串参考)+ 12个字节(对象标题)= ??字节

struct Student {}类教授{}

  • 堆栈:4个字节(int)+ 4个字节(字符串引用)+ 4个字节(教授参考)= 12个字节
  • 堆:0字节

struct Student {} struct Professor {}

  • 堆栈:4个字节(int)+ 4个字节(字符串引用)+教授的大小= ??字节
  • 堆:0字节

答案 2 :(得分:0)

您可以使用GC.GetTotalMemory(true)调用来测量实例化之前和之后的内存消耗,以测量堆分配