C# 对象创建时的内存分配

C# 对象创建时的内存分配,c#,C#,当我们实例化类/结构Student时,它将在堆栈和堆中分配多少内存 我猜id=4字节引用(32位机器),name=4字节引用,facultyAdvisor=4字节引用。所以堆栈中总共有12个字节,实际大小将在堆中。此堆大小可能会有所不同,这取决于我们为使用对象obj(Student obj=new Student())的字段(id、name、facultyAdvisor)指定的值 struct也是如此,对吗 public class Student { int id; string name;

当我们实例化类/结构Student时,它将在堆栈和堆中分配多少内存

我猜id=4字节引用(32位机器),name=4字节引用,facultyAdvisor=4字节引用。所以堆栈中总共有12个字节,实际大小将在堆中。此堆大小可能会有所不同,这取决于我们为使用对象obj(Student obj=new Student())的字段(id、name、facultyAdvisor)指定的值

struct也是如此,对吗

public class Student { int id; string name; Professor facultyAdvisor; }

public struct Student { int id; string name; Professor facultyAdvisor; }

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

首先请注意。。。对象的大小也是如此。但是在当前的实现中,
Student
中的字段的所有数据(当它是一个类时)都在堆上。有一个对象开销以及字段占用的内存,但所有这些都将在堆上

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

Student
是一个结构时,情况会有所变化:

  • 数据(堆栈或堆)的位置取决于值的使用方式——例如,如果它存储在类中的实例变量中,它将与其他数据一起位于堆上;如果它在局部变量中(同样,未捕获,不在迭代器块或异步方法中),那么它将在堆栈上
  • 您没有创建一个单独的对象,只是一个值,因此没有额外的开销-实际上只需要12个字节(假设
    Professor
    是一个引用类型)
我有几篇文章/帖子你可能会发现很有用:

  • (特别是字符串,但也包括其他类型)
  • -堆栈和堆,再次记住这是一个实现细节
编辑:解决
Professor
问题,假设
Professor
是一个类-除非明确创建
Professor
对象,否则
Student
中的引用将为空。创建一个新的
Student
不会因为存在一个该类型的字段而自动创建一个新的
Professor
。对
Professor
的引用只是
Student
数据的一部分-它存在于
id
所在的任何地方-因此如果
Student
是一个类,那么引用只存在于堆上,如果
Student
是一个结构,那么它取决于
Student
值的创建位置,如上所列。

假设32位CLR(在64位CLR上引用为64位),并且只考虑学生的堆分配


班级学生{}班级教授{}

  • 堆栈:4字节
  • 堆:4字节(int)+4字节(Professor Reference)+4字节(string Reference)+12字节(objectheader)=24字节
班级学生{}结构教授{}

  • 堆栈:4字节
  • 堆:4字节(int)+处理器大小+4字节(字符串引用)+12字节(对象头)=??字节
struct学生{}班教授{}

  • 堆栈:4字节(整数)+4字节(字符串引用)+4字节(教授引用)=12字节
  • 堆:0字节
struct学生{}struct教授{}

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

谢谢Jon-出于某种原因,我错过了那里的名字-EditeClass Student{}class Professor{}Stack:4字节堆:4字节(int)+4字节(Professor Reference)+4字节(string Reference)+12字节(object header)=24字节。在这种情况下,堆中将有4个字节(教授引用)?如果是的话,实际的物体在哪里?另外,正如u所说的堆栈中的4个字节,这个4字节堆栈引用指向所有字段(id、名称和facultyAdvisor)。是否可能?堆栈上的4个字节是指向堆上的学生对象(及其所有字段)的学生引用,professor引用与学生一起分配,但professor对象是heapHi上的单独分配,因为professor对象是堆上的单独分配,它的引用应该存储在堆栈上,对吗?它如何与堆中的学生对象一起出现。否-对教授的引用是学生状态的一部分,因此与学生对象一起存储在问题堆上。好心的answer@Alavudeen:完成,尽管我不太确定我是否理解编辑后的问题。如果我的编辑不能让你满意,请澄清问题。我用你的答案澄清了我编辑的问题。但仍然无法恢复conclusion@Alavudeen字体是的,恐怕是这样。就英语而言,你的问题没有真正的意义——我很感激它可能不是你的第一语言,但它确实让你很难回答:(你读过我链接的文章吗?它们非常详细地涵盖了所有这些内容。如果你已经彻底阅读了这些内容,但仍有疑问,请发布一段更具体的代码——最好是一个完整的程序——以及关于它的非常具体的问题。)。