什么时候在堆栈上为变量分配空间?

本文关键字:分配 空间 变量 堆栈 什么时候 | 更新日期: 2023-09-27 17:50:05

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

int c; // here
c = 5; // or here

什么时候在堆栈上为变量分配空间?

什么时候在堆栈上为变量分配空间?

你的问题假设变量的存储是在堆栈上分配的。不必如此。你刚刚说了"int a;",但没有指明它是局部变量还是字段,也没有指明其他重要信息,比如局部变量是否是匿名函数的封闭局部,或者该块是否是迭代器块。在许多情况下,变量不会占用堆栈空间,因为变量不是短暂存在的。

为了便于讨论,假设该变量是一个短暂的局部变量。它仍然可能不在堆栈上。它可能被注册了,特别是如果抖动知道它在一个有很多未使用寄存器的架构上。

假设该变量是一个短期局部变量,并且抖动没有选择注册它,那么何时分配堆栈空间?

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

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

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

如果你想问的是"堆栈指针什么时候被选中,以便有专门用于这个局部变量的堆栈空间",那么答案通常是"一旦控制进入方法"。这样做当然会触发我刚才提到的页面错误。

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

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

引自以下文章:

人们把值类型和引用类型的区别解释为"值类型在堆栈上,引用类型在堆上",这引起了很多混淆。这完全是不真实的(如前所述),本文试图在某种程度上澄清问题。"

.net框架中值类型和引用类型的内存分配

http://www.yoda.arachsys.com/csharp/memory.html

http://msdn.microsoft.com/en-us/magazine/cc163791.aspx

在创建线程时分配堆栈,然后根据需要扩展堆栈,可能以堆栈溢出结束。

编辑:啊,我现在看到这是引用堆栈内存具体。我的答案是堆内存。不过,为了子孙后代,我会继续写下去。

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

IEnumerable<String> myVariable;

你可以这样做:

myVariable = new List<String>();

你还可以这样做:

myVariable = new Stack<String>();

甚至更多,你可以让你自己的类充满大量需要大量内存的元数据,只要你正确实现了IEnumerable,你就可以:

myVariable = new MyIEnumerableClass<String>();
因此,(在一般意义上)在变量初始化之前,实际上无法知道需要多少内存。