.NET本地变量存储在哪里?

12
在IL中,你可以使用.locals指令来定义本地变量。这些变量存储在堆栈(stack)中还是堆(heap)中?
3个回答

9

使用参数的堆栈。 ..但是 .....
1)对于引用类型,只有引用存储在堆栈中,而不是其所指向的对象。实际的对象存储在堆上。
2)对于值类型,实际值存储在堆栈上。

现在当方法中的执行流到达结束括号时,堆栈上的值类型数据将被立即销毁,而堆上的引用类型对象(其引用在此方法的堆栈上)将交给垃圾收集系统进行收集,在适当时间由垃圾回收器自行决定。


2
这也是非常误导人的,原因与标记答案相同。而且绝对没有任何破坏发生。无论是在 IL 还是机器代码中都不会。堆栈位置只是被放弃了,并最终被另一个激活堆栈帧覆盖。即使引用类型在堆上的概念也不准确。内部化字符串实际上存储在加载器堆中,与静态变量存储的位置相同。细节,细节。 - Hans Passant
@Hans:感谢你提供的详细信息,非常感谢你的解释。 - explorer

9
这是JIT编译器的一项非常具体的实现细节。它会尽力将局部变量存储在CPU寄存器中,以提高效率。栈是通常的备份存储区,在没有足够的寄存器来存储所有局部变量时使用。
例如,x86和x64 jitters之间存在很大的差异。x64有更多可用的寄存器。这也适用于传递给方法的参数。x86允许在CPU寄存器中传递2个参数,而x64允许传递4个参数。此外,还可以存储在FPU堆栈或XMM寄存器中。因此,局部变量可以存储在四个不同的位置。

+1,在涉及IL时,人们对于本地变量和参数存在很多混淆。IL使用一个操作栈,但这与由C编译器生成的“cdecl”或“stdcall”调用约定所生成的“调用栈”并不直接对应。参数和本地变量都被视为编号槽位;仅在方法调用的参数从操作栈中弹出以加载到方法调用的参数槽位时,才存在与调用栈相似的地方。 - Dan Bryant

4
如果对象不是值类型,它将被分配在堆上,并在栈上存储对它的引用。否则,它将直接分配在栈上。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接