2008-10-29 75 views

回答

5

有3分不同的方式分配內存。

靜態:

這些約束,並在編譯時分配。全局靜態變量例如。

堆棧動態:

這些運行時綁定和壓入堆棧。如函數調用中的局部變量。

堆動態:

現在堆動態也有一些不同的「子類別」,如隱性和顯性的,但我不會去到那個細節。

當聲明

private MyClass item; // here? 

到MyClass的基準被壓入堆棧。這只是一個參考而已,僅此而已。它的值在那個點是空的。

public void MyMethod() 
{ 
    item = new MyClass(); // or here? 
} 

正是在這一點上,通過調用'new MyClass()'和item然後引用它來在堆上明確分配內存。

所以實際上,在你調用MyMethod之後你有兩個變量。引用類型命名的項目,以及項目引用的堆中未命名的變量的類型爲MyClass。

1

這是一個詭計的問題,這使我比我想象的要多得多。 :)

讓我們從基礎開始:

聲明一個變量不直接分配內存*爲它的引用類型。它確實這樣做值類型,因爲值類型在聲明點初始化。對於引用類型,對象的存儲在輸入其構造函數時分配。

*什麼時候不適用?

  • 在一個給定的類(這很可能是你的第一行)的第一次使用,任何類級別的靜態數據被初始化,如果類有一個靜態構造函數(這大概分配內存),它會也被稱爲。因此,你可以在變量聲明中實際分配一些內存(對於靜態成員)。
  • 從技術上講,聲明你的引用類型變量確實在棧上分配一些內存(就像Nicholas Mancuso提到的那樣) - 分配的內存是用於引用對象的堆棧級存儲。(不可否認,所述的參考值爲null,但一旦你初始化你的對象,一個有效的參考將在分配的內存中。)

我強烈推薦這個C-Sharp Corner article關於棧和堆分配的更多信息。

+0

非常好的答案,尼古拉斯留下的一些東西增加了暗示。我會投票,但他會得到答案。謝謝! – 2008-10-30 12:33:14

+0

他應該;他的回答更徹底。 :)他和我幾乎在同一時間回答,只是一分鐘左右。 :) – 2008-10-30 13:13:34

0

我強烈建議你看看Compact Framework Memory Management上的MSDN Webcase。它與桌面上的工作方式並不完全相同,本次講座涵蓋了大量的細節和圖形,有助於理解GC堆。