2011-07-24 38 views
2


我想知道 - 對象是如何存儲在內存中的?
我已經知道有一個引用(就像一個指針),它是一個int值,它包含存儲該對象的內存中的位置 - 但它存儲的究竟是什麼?
可以說我有ClassCint a, char b, long c, float dshort e - 我知道每個如何存儲每一個都有自己的一套位,但在每一個不同的位的數量 - 所以究竟怎樣C#知道哪些位應該訪問它,當我寫OBJ.cOBJ.b
是否有可能將整個(非靜態)對象轉換爲字節數組bit \位置和返回?

明顯 - 如果有像ClassC.TcpListener tcp這樣的東西 - 它是一個引用並存儲爲int(至少它具有相同的字節大小) - 但是,它仍然如何在int和指針之間有所不同?
C#中的對象如何存儲在內存中?

+1

」但它究竟存儲了多少?「 - 你能澄清一下你在找什麼嗎?堆vs堆棧? Endieness?還有別的嗎? – Oded

+1

請注意,這裏的大多數答案將是一個實現細節。引用很大程度上是不透明的 - 即使它在大多數情況下碰巧是一個指針,它也不是必需的。也;在x64引用是64位,而不是32(「int」) –

+1

此外,ECMA-335會給你一個完整的答案。當然,它有點乾燥。 –

回答

1

通常,這不是你需要關心的東西,除非你是P /調用C庫。

那麼C#如何知道當我寫入 OBJ.c或OBJ.b時應該訪問哪些位?

這取決於對象的StructLayout。有兩種可能的LayoutKind s。

缺省值爲Sequential,其中字段以與聲明相同的順序存儲,aligned正確。默認情況下,包含你的五場一個struct將被存儲爲:

  • 偏移0-3:int a
  • 偏移4-5:char b
  • 偏移6-7:填充
  • 偏移8 15:long c
  • 偏移16-19:float d
  • 偏移20-21:short e

由於vtable指針,垃圾回收器元數據等原因,A class可能會有略微不同的佈局。我不確定它是如何工作的。

其他LayoutKind是顯式的,您可以在其中明確指定字段偏移量。

是否有可能將整個(非靜態)對象轉換爲一個字節數組\位和回?

是的,Marshal類會讓你這樣做。請參閱StructureToPtrPtrToStructure

它是一個參考,並存儲爲int

指針不是存儲爲int秒。這在64位系統上不起作用。代替使用IntPtr

但仍然,int和指針之間有什麼區別?

在哪個級別? C#? CIL?機器語言? 「

+0

「對象的StructLayout」似乎有些矛盾...... –

+0

我會檢查它。謝謝! –

+0

'Marshal'類不會讓你看看它們在內存中的字節,至少並不總是如此。它所做的是將其轉換爲適合非託管代碼的表單。翻譯通常不會做任何事情,但並非總是如此。 – svick

2

C#實際上不知道在哪裏訪問對象中的成員。它是決定對象佈局的JIT編譯器。

可以爲成員添加屬性,以便JIT編譯器以特定的方式放置成員,這樣可以將所有成員作爲內存塊訪問,但這很少值得付出。

注意:指針在32位系統上是32位(int),在64位系統上是64位(長)。

+0

所以這就是爲什麼64位系統需要一堆內存>< –