引用类型存在于堆上,值类型存在于堆栈中

Won*_*ing 14 c#

在阅读"C#in Depth"时,我正在阅读"引用类型存活在堆上,值类型存在于堆栈中"部分.

现在我能理解的是(主要用于ref类型):

class Program
{
    int a = 5;  // stored in heap

    public void Add(int x, int y) // x,y stored in stack
    {
        int c = x + y;  // c  stored in stack
    }
}
Run Code Online (Sandbox Code Playgroud)

只想澄清我的假设是否正确.谢谢.编辑:我应该使用差异变量,我认为它造成了混乱.所以我修改了代码.

编辑:是的,正如乔恩所说 - 这是一个神话,我应该提到这一点.我道歉.

sir*_*ide 14

http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

整个"堆上的引用类型,堆栈上的值类型"不仅是一种不好的方式来看待它,但它也是错误的.

  • @siride:我应该指出,该部分特别将其称为神话:) (5认同)
  • @siride:我的意思是我有一个神话列表,我明确地说这是错误的,而“引用类型存在于堆中,值类型存在于堆栈中”就是这些神话之一。这里的问题听起来像是书在断言它,而实际上是在反驳它:) (2认同)

Han*_*ant 11

对于幕后发生的事情,我可能是一个有用的抽象概念.但在任何当前发布的JIT编译器版本中都不是这样.这可能是问题的症结所在,实际的分配位置是JIT编译器实现细节.

至少有六个地方的值类型值可以与主流(x86和x64)抖动一起使用:

  • 在堆栈框架中,通过局部变量声明或方法调用放在那里
  • 在CPU寄存器中,由JIT在Release版本中执行的非常常见的优化.并且用于将参数传递给方法,前两个x86,四个用于x64.和可能的局部变量
  • 在FPU堆栈上,x86抖动用于浮点值
  • 在GC堆上,当值是引用类型的一部分时
  • 在变量声明为static时,在AppDomain的加载器堆上
  • 当变量具有[ThreadStatic]属性时,在线程局部存储中.

通常在GC堆上分配引用类型对象.但我知道一个特定的异常,源代码中从文字产生的实习字符串在AppDomain的加载器堆中分配.这完全像运行时的​​对象,除了它没有链接到GC堆,收集器根本看不到它.

解决您的代码段:

  • 是的,"a"很可能存储在GG堆上
  • "x"始终在x86和x64上的CPU寄存器中传递."y"将位于x64上的CPU寄存器中,即x86上的堆栈.
  • "c"可能根本不存在,由JIT编译器删除,因为代码没有效果.

  • x86 核心有两个 CPU 寄存器,x64 核心有四个。“this”指针需要一个。 (2认同)