2010-04-02 59 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

相關問題