2010-08-01 102 views
3

這是很長的時間,因爲我試圖找出有關靜態類的真相。我的觀點是:當使用新操作符時,值類型被分配到堆棧中,堆中的引用類型。但是靜態類的本質是你不能創建它的一個實例,並且確定它不是一個值類型。所以我有一個問題,在什麼時候CLR爲靜態內容分配內存?關於什麼時候......我在編譯期間假設一個程序集被構建時,但我不確定。以及關於哪裏...當我試圖找出我閱讀J.Richter的「通過C#的CLR」,並且他寫道,當您創建該特定實例時,實例類的靜態方法將分配在堆中類(與類型對象指針和同步塊索引一起)。但我不明白。它是靜態的。它不應該依賴於任何對象的狀態。所以,請減輕我。靜態類/成員分配在哪裏?

+1

靜態成員和構造函數(我相信您引用的文本引用的)和靜態類之間存在差異。你知道這個區別嗎?如果是這樣,你具體詢問哪些? – strager 2010-08-01 22:47:07

+0

好...我知道的區別不在內存分配,是嗎? 在這裏,我在問靜態類的內存分配。我只是因爲裏希特書中的一個例子而引發了靜態方法。但如果分配靜態類和實例類的靜態成員之間有任何區別,我想知道它。 – Mark 2010-08-01 23:02:34

+1

值總是在堆棧上分配的,這不是事實。當然是 – 2010-08-01 23:05:47

回答

1

除了用戶堆內存之外,CLR還在堆上保存各種簿記信息&元數據。這包括你執行的方法的實際代碼,以及每種加載到AppDomain中的類型的Type對象 - 它是名稱,重載,是抽象的還是密封的,以及定義的所有方法的列表(包括靜態和實例)方式。

當您執行一個方法時,CLR將在堆的CLR專用部分的相應Type對象中查找方法信息並執行該方法。實例和靜態方法之間的唯一區別是實例方法在指向方法執行的實例的方法參數中包含額外的'this'指針。

因此,靜態信息與所有其他信息一起存儲在堆上,但它不與任何特定對象實例關聯。

+0

是的,這很有道理!謝謝!所以,所有這些實例和靜態類的東西看起來都是騙人的。它只是一個額外的「this」指針,但它們都保存在同一個地方......同樣的方式。非常感謝 – Mark 2010-08-01 23:31:08

4

CLR維護與AppDomain相關的幾個堆,統稱爲「加載堆」。它們與垃圾收集堆不同,因爲它們不包含可收集對象,大多數類型相關的數據。 AppDomain生命週期中的數據類型。

靜態變量的空間分配在其中的一個HighFrequencyHeap中。 JIT編譯器進行分配,它直接生成的代碼引用內存位置。背景信息在MSDN Magazine article