引用类型的堆栈条目包含什么?

时间:2016-06-21 12:04:31

标签: c# .net memory

我清楚地了解了参考和值类型在.NET中的工作方式。我知道引用类型的堆栈上的条目包含指向堆上的内存位置的指针。我似乎无法找到有关堆栈条目包含的其他内容的详细信息。所以,鉴于以下内容:

Customer customer;
customer = new Customer();

在第一行代码之后,将存在包含空指针的堆栈上的条目。该条目是否还包含识别名称“customer”?它是否包含类型信息?

我是否从根本上误解了某些事情?

3 个答案:

答案 0 :(得分:11)

仅存储指向对象的指针,没有别的。不在堆栈上,它存储在处理器寄存器中。只有当方法很大并且寄存器更好地用于其他目的时,它才会存储在堆栈中。做出决定是the optimizer的工作。这通常不太可能发生,因为您可能正在使用Customer类的属性和方法,因此将指针保存在寄存器中是有效的。

否则,这是NullReferenceException可以告诉您什么引用无效的基本原因。将指针值关联回命名的"客户"变量只能由调试器完成。它需要PDB文件才能知道变量的名称,该名称在程序集的元数据中不存在。这就是为什么你不能使用Reflection来发现局部变量名和值的基本原因。

这也是为什么调试只有在项目的Debug版本中使用它时才能正常工作。这会禁用优化器并将指针值始终存储回堆栈插槽,从而允许调试器可靠地将其读回。这是一个很大的代价,你应该只部署项目的Release版本的基本原因。

答案 1 :(得分:2)

变量名customer仅存在于源代码中(因为它对您的计算机不感兴趣)。在运行时,没有人知道如何在代码中调用变量。

Jon Skeet写了一篇关于what is stored on the heap and what goes to the stack的好文章。 第一段(变量中的内容是什么?)应该回答你的问题:

  

引用类型变量的值始终是引用或null。如果它是引用,则它必须是对与变量类型兼容的对象的引用。例如,声明为Stream s的变量将始终具有null或对Stream类的实例的引用的值。 (请注意,Stream的子类的实例,例如FileStream,也是Stream的实例。)与变量关联的内存槽只是引用的大小,无论它指的实际物体多么大。 (例如,在32位版本的.NET上,引用类型变量的插槽总是只有4个字节。)

答案 2 :(得分:2)

1-变量名与参考一起存储在内存中。

2- A null引用不存储对象的类型。

说明事项的例子:

string str = null;

if(str is String)
{
    Console.WriteLine("I'm a string");
}
else
{
    Console.WriteLine("I'm not a string");
}

// This will print: "I'm not a string"

您实际上在告诉编译器,允许我使用str的映射存储位置仅创建字符串引用。

  

变量代表存储位置。每个变量都有一个类型   确定哪些值可以存储在变量