如何演示c#变量的存储位置,堆栈或堆栈

时间:2014-07-31 03:21:20

标签: c#

我知道c#,就像Java一样,将源代码转换为字节码并由VM运行,因为C#案例是CIL存储在汇编中并由CLR执行。开发人员几乎不需要关心变量在堆栈上或堆上的位置(由GC处理)作为c ++,对吧?

他们是否有任何快速而直接的方式来证明变量存储在堆栈或堆上?例如,如果我告诉某人,引用类型变量存储在堆上,或者本地值类型变量存储在堆栈上(对吗?)。我怎样才能明确地表明这一点?在C ++中,我可以获取变量的内存地址,并通过VS内存窗口查看存储在堆栈或堆内存中的值。

1 个答案:

答案 0 :(得分:23)

  

开发人员几乎不需要关心变量在堆栈或堆上的位置,对吧?

右。为存储选择的技术是运行时的实现细节。

我注意到您已将省略的寄存器作为存储的可能选择。注册了很多变量,所以它们既不会堆栈也不会堆积。

更好的方法是考虑短期存储长期存储

  

是否有任何快速而直接的方法来证明变量存储在堆栈上或堆上?

尝试计算变量的生命周期。如果您可以轻松地这样做,并且生命周期小于或等于创建它的方法激活的持续时间,那么它很可能在短期池中。如果没有,它可能在长期池中。

  

在C ++中,我可以获取变量的内存地址,并通过VS内存窗口查看存储在堆栈或堆内存中的值。

使用&运算符可以更改存储变量的位置!如果您获取变量的地址,那么就无法注册因为寄存器没有地址。改变它试图描述的东西的技术是一种不可靠的技术。

另外,您可能忘记了在C ++中堆栈和堆不是唯一可能的存储位置。

  

例如,如果我告诉某人引用类型变量存储在堆上,或者本地值类型变量存储在堆栈上(对吗?)。我该如何明确地表明这一点?

由于这些陈述是 false ,因此您无法在所有中显示。简单地说,引用总是在堆上,并且值类型的局部变量在堆栈上。例如:

void M()
{
    string s = "";
    ...

空字符串位于长期存储池中,但空字符串首先不存储在s中。 对空字符串的引用存储在s中。该引用可以放在短期池中。

请记住,参考类型的实际参与者不会进入变量 。引用类型的变量包含引用 - 这就是他们称为引用类型的原因。

现在,引用类型的字段变量,而变量没有已知的生命周期,因此 变量必须放在长期存储池中:

class C { public int x; }
...
C M() { C c = new C(); return c; }

x是值类型的变量,但由于它是属于引用类型的字段,因此它必须位于长期池中。 c是引用类型的变量,因此它包含引用;变量c 的生命周期很短,因此c会出现在短期池中。再次不要将引用与引用的内容混淆

示例:

Action<int> M()
{
    int x = 123;
    return y => { x = y; Console.WriteLine(x); };
}

本地变量x属于值类型,但您无法计算其生命周期,因此它必须位于长期存储池中。

由于你的声明引用类型的变量在堆上,而值类型的局部变量在堆栈上是错误的,所以没有办法证明它的真实性。