【问题标题】:What does it mean when constant local variables are stored in the assembly data region, while non-constant local variables are stored on the stack?当常量局部变量存储在程序集数据区域中,而非常量局部变量存储在堆栈中时,这意味着什么?
【发布时间】:2026-02-01 13:25:01
【问题描述】:

我正在阅读这个wikibook,但不明白这在局部变量部分中的含义是什么? ELI5 会很有帮助

【问题讨论】:

  • 常量局部变量是不在方法(函数或子例程)内部的公共变量。因此它们被放入一个名为“程序集数据区域”的表中。方法中的变量放在执行堆栈上。当调用一个方法时,编译器会在执行堆栈上保留内存,这是执行该方法所需的所有变量的总大小。因此,如果一个方法声明 int a;int b;诠释 c;一个整数是 4 个字节,因此堆栈上为局部变量保留了 4 x 3 = 12 个字节。
  • @jdweng - 常量 local 变量 在方法中声明。这就是使它们本地化的原因。
  • @jdweng - 并且“不在方法内部的变量”在堆上,而不是在数据区域中。那是关于“变量”与“恒定”的关系。

标签: c# constants local-variables


【解决方案1】:

有趣的事实 - 堆栈是一个几乎无关紧要的实现细节。 C# 规范中对stack 的大多数引用是对玩具Stack<T> 类的引用,而不是对执行堆栈的引用。

我们来个玩具方法:

public int Compute(int value)
{
   int b = value/2;
   if (b > 10){
      return b + Compute(b);
   }
   return b - 4;
}

这个Compute 方法需要某个地方,它可以存储b 变量的内容。重要的是,这个方法可能recurse1,也就是说,它可能会调用自身,可能是重复的,重要的是方法的每次执行都保留b 变量的它自己的副本。如果内存中只有一个b 变量的存储空间,那么递归是不可能的。2

因此,变量的存储必须动态提供 - 每次输入方法时,都必须为局部变量提供新的存储。提供这种存储的一种特别常见的方式是通过“堆栈帧”或“激活记录”。 实际需要多少存储空间取决于涉及优化和变量生命周期的复杂讨论,但在简单的情况下,我们说堆栈帧包含每个局部变量的足够存储空间。

但是,const 本地变量是特殊变量 - 因为它们不会变化。因此,作为一种优化,我们可以在某处仅存储此变量的一个副本,并且运行的每个 Compute 实例都可以引用该单个副本。


1在这里,它是微不足道的递归,但不必如此 - 可以通过对其他方法的大量中间方法调用来隐藏递归。

2我们也不能允许该方法被多个线程调用。

【讨论】: