【问题标题】:Where are .NET local variables stored?.NET 局部变量存储在哪里?
【发布时间】:2010-09-29 14:16:05
【问题描述】:

在 IL 中,您可以使用 .locals 指令定义局部变量。这些变量存储在哪里,堆栈还是堆?

【问题讨论】:

    标签: .net local-variables


    【解决方案1】:

    这在很大程度上是 JIT 编译器的实现细节。它将非常努力地将局部变量存储在 CPU 寄存器中,非常高效。堆栈是通常的后备存储,以防没有足够的寄存器可用于存储所有局部变量。

    例如,x86 和 x64 抖动之间的巨大差异。 x64 有更多可用的寄存器。这也适用于传递给方法的参数。 x86 允许在 CPU 寄存器中传递 2 个,x64 允许 4 个。加上可以存储在 FPU 堆栈或 XMM 寄存器中的任何内容。所以,实际上有四个不同的地方可以存储一个局部变量。

    【讨论】:

    • +1,当涉及到 IL 时,有很多关于局部变量和参数的混淆。 IL 使用操作堆栈,但这并不直接对应于“调用堆栈”,例如由具有“cdecl”或“stdcall”调用约定的 C 编译器生成的堆栈。参数和局部变量都被视为编号槽;唯一与调用堆栈相似的地方是方法调用的参数从操作堆栈中弹出以加载到方法调用的参数槽中。
    【解决方案2】:

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

    现在,当方法中的执行流程到达右大括号时,堆栈上的值类型数据在此处被销毁,然后在堆上的引用类型对象(其引用在此方法的堆栈)在垃圾收集器自己决定的适当时间移交给垃圾收集系统进行收集。

    【讨论】:

    • 由于与标记答案相同的原因,这也非常具有误导性。另外,绝对不会发生破坏。在 IL 和机器代码中都没有。堆栈位置被简单地放弃并最终被另一个激活堆栈帧覆盖。甚至引用类型在堆上的概念也不准确。内部字符串实际上存储在加载程序堆中,与保存静态变量的位置相同。细节,细节。
    • @Hans:感谢您提供详细信息...感谢您的解释。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-18
      • 2017-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多