2011-11-16 86 views
1

當我調試這些代碼行時,我可以觀察到ms/ms2是值類型的實例,它們分配在堆棧上,並且o(boxed MyStruct實例)是引用類型並分配到託管堆中。如何解釋堆和堆棧不會彼此成長

我可以在Visual Studio中的Watch窗口中查看ms和ms2的地址,它們分別是0x0024f104和0x0024f0f0。所以堆棧正朝着地址空間的底部增長。由於堆棧和堆彼此增長,託管堆的地址區域應該低於0x0024f0f0。但o的地址實際上是0x01e9312c,這意味着堆不會朝着堆棧增長(儘管我可以觀察堆中新對象何時分配,它們的地址確實正在增長)。

有人可以幫助解釋這個嗎?

MyStruct ms = new MyStruct(1, 2, 4, 8); //0x0024f104, 16 bytes for ms 
Object o = ms;       //0x0024f100, 4 bytes for variable o 
MyStruct ms2 = (MyStruct)o;    //0x0024f0f0, 16 bytes for ms2 
+0

我發現這個「地址空間佈局隨機化默認啓用從Vista開始」(http://en.wikipedia.org/wiki/Address_space_layout_randomization#Microsoft_Windows)。所以是的,我現在承認「堆棧和堆向彼此成長」不再有效。 – kennyzx

+0

不,這不是理由。這只是內存管理方面的一個方面。在進程的虛擬地址空間內的棧和其他內存部分被分配*在剛好可用的位置,而不是因爲需要「增長」。 –

回答

1

堆棧和頭朝向彼此增長是一個30多年前的有效概念。

通常,您不必關心對象所在的內存位置。

+0

除非你試圖實施攻擊;) – lc2817

+1

或者設計類似於sql server的東西,但在這種情況下,你不會在第一個地方問這樣的問題:-) –

+0

在我看來,它仍然是一個有效的概念,進程的虛擬地址空間是分區的,這在現代操作系統中並沒有改變。我懷疑在這種情況下,公共語言運行時(Common Language Runtime,CLR)會做一些額外的工作,因此堆可以位於地址空間的任何地方,畢竟它被稱爲「託管堆」。 – kennyzx