2010-04-02 103 views
16

我昨天看到一个问题,提出了(对我来说)另一个问题。请看下面的代码:类的字段,它们是存储在堆栈还是堆?

public class Class1 
{ 
    int A; //as I uderstand, int is value type and therefore lives in the stack 
} 

class Class2 
{ 
    Run() 
    { 
     Class1 instance1 = new Class1(); 
     instance1.A = 10; //it points to value type, but isnt this reference (on heap)? 
    } 
} 

或者在创建Class1的实例时,它的字段类型也在堆上创建?但是,我不明白什么时候它真的会在堆栈上,因为几乎总是需要创建一个对象的实例才能使用它的字段。

+0

类名是不允许的题外话,开始与多家 – cpalmer 2010-04-02 06:35:26

+0

:你有没有 – thelost 2010-04-02 06:36:49

+0

感谢了无效类的名称,固定的:) – Mirek 2010-04-02 06:36:57

回答

3

本地结构(值类型)变量存储在堆栈中,类的值类型字段存储在堆上。

+7

除非(1)局部变量是匿名方法或lambda表达式的封闭外部局部变量,或者(2)局部变量位于迭代器块中,或者(3)抖动决定使用寄存器而不是堆栈。 – 2010-04-02 15:57:58

+0

就存储而言,instance1变量会发生什么变化。它是一个引用类型,但同时它对Run()函数是本地的。将instance1保存在堆栈或堆上? – RBT 2015-03-17 01:11:29

+0

对不起@EricLippert另一个评论,但我试图编辑我的前一个,但不能及时做到这一点。为了增加上述问题的清晰度,我想问两个问题1.参考实例1将保存在哪里。 instance1仅仅是一个引用,它将实际对象实例所在的内存地址保存为2.实例1引用的Class1的实例将驻留在该对象中。这里的对象是Class1的一个实例,但在Run()方法中有一个局部范围。 – RBT 2015-03-17 01:31:24

2

Ok int是一个值类型,但'1'(一个类的可怕名称)是一个引用类型。这意味着任何“1”的实例都在堆上。

36

据我所知,int是值类型,因此住在堆栈

你的理解是不正确。值类型被称为“值类型”,因为它们是按值复制的。引用类型被称为“引用类型”,因为它们通过引用被复制。 “价值类型总是活在堆栈中”并非完全正确。如果这是真的,他们将被称为“堆栈类型”和“堆类型”。

事实是,这是一个实现细节。不同的框架实现可以根据需要选择使用堆栈和堆。下面是Microsoft实现的方式:

  • 引用类型变量的值是对堆内存的引用。参考基本上是一个32位或64位整数。
  • 值类型变量的值是它的值。
  • 局部变量的值存储在堆栈中,除非局部变量位于迭代器块中,或者是匿名方法或lambda表达式的外部变量的关闭。在这些情况下,局部变量的值存储在堆中。除非局部变量可以被优化掉,在这种情况下根本就没有存储。或者也许它们可以被注册,在这种情况下,它们既不在堆栈中,也不在堆中,它们在处理器寄存器中。
  • 引用类型和静态变量的实例变量的值存储在堆上。

这是明确的吗?

它指向值类型,但不是此引用(在堆上)?

字段“A”是值类型的。它是一个字段,因此该变量存储在堆中。

在创建Class 1的情况下,它的字段类型在堆上创建的呢?

实例变量的存储位于堆上,是的。

但是,我不明白什么时候它真的会在堆栈上,因为几乎总是需要创建对象的实例才能使用它的字段。

它永远不会在堆栈上。正如我上面所说的,堆栈中唯一的东西是本地变量(和编译器生成的临时对象),它们不是闭包的lambda或匿名方法的本地数据,并且不在迭代器块中。当然,如果有自由寄存器,抖动可以完全自由地将它们放在堆栈上并放入寄存器。

但是真的,我不得不问,为什么你在乎堆栈上发生了什么以及堆上发生了什么?堆栈上的东西是我们可以便宜地放在堆栈上的东西;一切都在堆上。

+0

我从John Sharp那里得到了这本书,指出“在堆上创建值类型,同时在堆上创建引用类型”。也不明白。 – Thomas 2010-04-02 16:28:56

+0

“实例和静态变量的值存储在堆中。”除了存储在堆栈上的实例的struct-typed实例变量外,对吗? – Joren 2010-04-02 22:45:59

+2

“为什么你关心堆栈上发生了什么以及堆栈上发生了什么” - 因为一些采访者非常喜欢这样的问题,并且很多人都失败了,因为无处不在,int变量总是存储在堆栈中,而不是“那走在堆栈上的唯一的东西是局部变量” – Laserson 2013-10-03 06:47:41

相关问题