在声明或初始化期间分配空间:
int c; // here
c = 5; // or here
答案 0 :(得分:12)
何时在堆栈上分配变量的空间?
您的问题预先假定变量的存储在堆栈上分配。它不一定是。你刚才说“int a;”不指示那是局部变量还是字段,并且没有指示其他重要信息,例如局部变量是否是匿名函数的封闭本地,或者块是否是迭代器块。在许多情况下,变量不会消耗堆栈空间,因为变量不是短暂的。
假设为了参数,变量是一个短暂的局部变量。它仍然可能不在堆栈中。它可能已被注册,特别是如果抖动知道它位于具有大量未使用寄存器的架构上。
假设为了参数,变量是一个短暂的局部变量,并且抖动没有选择注册它,何时分配了堆栈空间?
嗯,再次,你假设抖动使用堆栈作为临时池;虽然这是一种方便的数据结构,但抖动允许宽幅度。临时池可以从堆中分配,也可以有多个堆栈;一些体系结构支持将数据堆栈与调用堆栈分离,以防止堆栈粉碎攻击。
假设变量是一个短暂的局部变量,并且抖动选择不注册它,并且临时池在调用堆栈上,何时分配它的堆栈空间?
那么现在它取决于“分配”的含义。整个百万字节的堆栈在虚拟内存系统中保留并积极提交,因此答案是“一旦创建了线程,就会分配此线程中堆栈中所有内容的堆栈空间,并保留分配“。当然它在页面文件中保持分配。在页面错误从磁盘上的页面文件中引入之前,该堆栈不会移动到硬件(RAM)中。
如果您要问的是“堆栈指针何时被撞击以便有特定的堆栈空间可用于此局部变量”,那么答案通常是“一旦控制进入方法”。这样做当然可以触发我刚才提到的页面错误。
我很想知道你为什么关心。它有什么不同?
答案 1 :(得分:1)
首先,要清除每次在Stack内存上分配值类型的混淆,请阅读以下链接。
引用下面的文章:
“人们解释了价值类型和引用类型之间的差异已经造成了很多混乱,因为”值类型在堆栈上,引用类型在堆上“。这完全是不真实的(如上所述)和本文试图在某种程度上澄清问题。“
memory allocation of value types and reference types in .net framework
答案 2 :(得分:0)
在创建线程时分配堆栈,然后按需扩展,可能以堆栈溢出结束。
答案 3 :(得分:-2)
我很确定它是在初始化期间,就好像你有一个像
这样的对象IEnumerable<String> myVariable;
你可以做到:
myVariable = new List<String>();
你还可以这样做:
myVariable = new Stack<String>();
更重要的是,你可以让自己的类充满大量需要大量内存的元数据,只要你正确地实现IEnumerable,你就可以这样做:
myVariable = new MyIEnumerableClass<String>();
因此,(在一般意义上)直到变量被初始化,没有办法实际知道需要多少内存。