C# 何时在堆栈上为变量分配空间?

C# 何时在堆栈上为变量分配空间?,c#,C#,在声明或初始化期间是否分配了空间: int c; // here c = 5; // or here 编辑:啊,我现在明白了,这是专门引用堆栈内存的。我的答案是堆内存。不过,我会为子孙后代继续保持下去 我相当确定它是在初始化期间,就像您有一个对象,例如 IEnumerable<String> myVariable; IEnumerable myVariable; 你可以切实做到: myVariable = new List<String>(); myVariab

在声明或初始化期间是否分配了空间:

int c; // here

c = 5; // or here

编辑:啊,我现在明白了,这是专门引用堆栈内存的。我的答案是堆内存。不过,我会为子孙后代继续保持下去

我相当确定它是在初始化期间,就像您有一个对象,例如

IEnumerable<String> myVariable;
IEnumerable myVariable;
你可以切实做到:

myVariable = new List<String>();
myVariable=newlist();
您还可以执行以下操作:

myVariable = new Stack<String>();
myVariable=newstack();
更重要的是,您可以让自己的类充满大量需要大量内存的元数据,只要正确实现IEnumerable,您就可以:

myVariable = new MyIEnumerableClass<String>();
myVariable=newmyIEnumerableclass();

因此,(在一般意义上)在初始化变量之前,实际上无法知道需要多少内存。

在创建线程时分配堆栈,然后按需扩展,可能会导致堆栈溢出。

首先,要消除每次值类型仅在堆栈内存上分配的混淆,请阅读下面的链接

引用以下文章:

“人们将值类型和引用类型之间的区别解释为“值类型在堆栈上,引用类型在堆上”,这造成了很多混乱。这完全是不真实的(如上所述),本文试图在某种程度上澄清问题。”

何时在堆栈上为变量分配空间

您的问题假定在堆栈上分配了变量的存储。不必如此。您刚才说的“int a;”没有指明这是局部变量还是字段,也没有指明其他重要信息,例如局部变量是否是匿名函数的闭覆盖局部,或者块是否是迭代器块。在许多这样的场景中,变量不会占用堆栈空间,因为变量不是短期的

为便于论证,假设该变量是短期局部变量。它可能仍然不在堆栈上。它可能被注册,特别是当抖动知道它在一个有大量未使用寄存器的体系结构上时

为了论证,假设该变量是一个短期局部变量,并且抖动没有选择注册它,那么堆栈空间是什么时候分配的

那么,再一次,您假设抖动使用堆栈作为临时池;虽然这是一种方便的数据结构,但抖动是允许的。临时池可以从堆外分配,也可以有多个堆栈;一些体系结构支持将数据堆栈与调用堆栈分离,以防止堆栈破坏攻击

假设变量是一个短期局部变量,抖动选择不注册它,并且临时池在调用堆栈上,什么时候为它分配堆栈空间

这取决于你所说的“分配”是什么意思。整个百万字节的堆栈都保留在虚拟内存系统中,并积极提交,因此答案是“一旦创建了线程,该线程中堆栈上的所有内容的堆栈空间都将被分配,并保持分配状态。”当然,它将保持在页面文件中的分配状态。直到页面错误将该堆栈从磁盘上的页面文件引入,该堆栈才会移动到硬件(RAM)中

如果您想问的是“什么时候堆栈指针会发生碰撞,从而有专门用于该局部变量的堆栈空间”,那么答案通常是“一旦控件进入该方法”。这样做当然会触发我刚才提到的页面错误


我很想知道你为什么在乎。这有什么区别?

可能两者都没有。我认为它必须在输入包含方法时分配。你怎么知道它在堆栈上?@lukas,因为他没有使用
new
关键字,我认为它是一种值类型而不是引用类型堆栈上的局部变量。它们引用的对象可能存在于堆上。@David Heffernan:如果局部变量存在于寄存器中,它们就不会存在于堆栈上。显然,创建线程时堆栈内存没有分配。好吧,你每天都能学到新东西!您的答案是正确的,但它显示了在虚拟内存系统中保留和提交页面之间的混淆。在win32中,创建线程会立即保留一百万个连续字节的堆栈页。这些页面由保护页面绑定,当被命中时会抛出堆栈外异常。在非托管代码中,堆栈空间会自动扩展,以在堆栈增长时提交保留的虚拟内存页。在托管代码中,页面的提交更加积极。记住,保留和提交页面是有区别的;别把他们搞混了。@eric你说得对,我对保留、承诺等的理解很差。我认为在创建线程时堆栈是保留的,但在需要时提交?你所说的托管堆栈更加积极地投入是什么意思?乔·达菲(Joe Duffy)比我描述得更好。(顺便说一句,我惊讶地发现我们这样做了;我是直到最近才意识到这一奇怪现象的人之一。)@eric这确实看起来很奇怪。非常感谢分享您的知识。然而,阅读这篇文章让我更加深刻地意识到,我对虚拟内存的了解还不够。总是要学习更多!你描述它何时被保留。什么时候分配的问题有意义吗?@David:你说得对,我的术语太草率了。我会试着澄清课文。这是一个令人困惑的问题。即使
c
存储在堆栈上,如果可以重用另一个本地的空间,也可能无法为其分配空间。@Eric,th