2017-03-08 51 views
0

我只是第二年試圖學習更多的計算機科學家學生。我正在閱讀一本c#書:「簡單的c#」,我遇到了這個段落關於存儲在C#標題。C#和CLR中值類型的標題和浪費空間的存儲

值類型實例佔據了存儲其字段所需的內存。在 這個例子中,點需要八個字節的內存:

結構點 { INT X; // 4字節 int y; // 4個字節 }

技術上,類型內的CLR位置的字段在 地址是這樣的字段的大小的倍數(多達八個的 最大字節)。因此,以下內容實際上消耗了16個字節的內存(第一個字段後面的7個字節「浪費」): struct A {byte b;長我} 您可以覆蓋這個行爲與StructLayout 屬性

我的第一個問題是:爲什麼只有16個字節,爲什麼不是8或32個或其他數量的,8

我的第二個問題多是?爲什麼浪費了

+1

http://stackoverflow.com/a/42439111/17034 –

+1

的可能的複製[爲什麼結構A的尺寸不與相同的字段結構B的相等的大小?](http://stackoverflow.com/questions/42438397 /爲什麼結構體的大小不等於struct-b-with-same-fields) –

回答

0

在C#中,intSystem.Int32的別名,它是一個32位有符號整數,它是4個字節。

當與機器字邊界對齊時,處理器在64位邊界處訪問內存通常更有效,因此編譯器可能會將結構成員與所考慮的內容對齊,並且實際上將空閒空間留在物理結構使其更快地訪問它們。

+0

謝謝你的迴應。它總是這樣工作嗎?例如,當它與長(64位)一起工作時,是否會在內存中分配128位? –

+0

號碼對齊是每臺機器。在32位處理器上,它有利於在32位邊界上進行對齊。未來,在128位處理器上,它可能會對齊128位金額。這取決於編譯器。在互操作時可以使用強制「包裝」,因爲其他系統可能需要特定的對齊。通常情況下,你完全忽略它,不用擔心編譯器會有什麼魔力。 – Tim

1
struct A { byte b; long l; } 

上述struct的存儲器佈局可能類似於以下:

0 1 2 3 4 5 6 7 8 9 a b c d e f 
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 
| b | | | | | | | | l | l | l | l | l | l | l | l | 
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 

byte b被放置在結構的開始(開始索引0)。它佔用一個字節,所以下一個字段的起始索引將爲1(或更大)。 long l將佔用8個字節,因此它必須以8的倍數開始索引。運行時將嘗試將該字段放置在下一個可能的索引處,以使結構體的大小超出其所需的大小。這就是爲什麼它將被放置在起始偏移8處。

字節1到7將因此最終未被任何字段struct A佔用。它們不被A的任何字段所使用,並且因爲.NET對象在內存中不互相覆蓋,所以沒有任何東西可以使用或訪問這7個字節。它們僅保留爲A的實例,但不包含任何內容,因此它們的空間實際上被浪費了。

2

計算機體系結構將最小可尋址空間確定爲「單詞」。例如,在32位體系結構中,字是32位或4字節。對於64位體系結構來說它是它的兩倍。處理器操作對字而不是字節進行處理。

因此,想象在32位體系結構上的struct MyStruct {byte a; long b;},這需要3個字(12個字節)。而在64位體系結構中,這需要16個字節。

// 8-bit word size (3 1-byte words or 3 bytes) - this is the most compact it can be, but we don't use 8-bit processors. 
|1|1|2|3|4|5|6|7|8| 
|a|b|b|b|b|b|b|b|b| 

// 32-bit word size (3 4-byte words or 12 bytes) 
|1234|1234|1234| 
|a---|bbbb bbbb| 

// 64-bit word size (2 8-byte words or 16-bytes) 
|12345678|12345678| 
|a-------|bbbbbbbb| 
+0

+1,但可能會更精確一點,儘管處理器*可以*操作非字寬的數據,但在訪問內存中沒有字對齊的數據時,性能可能會受到影響。 – stakx

相關問題