一直有一個小小的疑惑——.NET一個對象或者一個集合佔多少內存?有沒有很快速的方法獲取,而不是簡單的估計分析對象大小?html
查了MSDN,和一些其餘人的分析,獲得解決是託管代碼對象的大小沒法真實的獲得,由於存在託管對象轉化成非託管的CLR優化。但我仍然不死心,非要弄個究竟!好吧,最終獲得一些結果了。佈局
sizeof關鍵字,用於獲取值類型的大小,如int(佔4個字節),char(2個字節);而且sizeof 運算符僅適用於值類型,而不適用於引用類型。因此針對對象改關鍵字沒法使用。優化
查閱msdn,發現對象Marshal.SizeOf 方法,解釋爲返回類的非託管大小;可是仍然不能使用,由於針對的是非託管代碼,若是直接使用一個類的對象,會報一個錯誤:"不能做爲非託管結構進行封送處理;沒法計算有意義的大小或偏移量。";這是由於對象在內存中實際大小並非固定的,可能此次運行一個值,下次就是另一個值了,存在優化!spa
因此爲了固定一個對象的大小,必須告訴CLR不優化對象在內存中的大小。這就須要在聲明類的時候加上[StructLayout(LayoutKind.Sequential)]這個特性;code
StructLayoutAttribute 類使用戶能夠控制類或結構的數據字段的物理佈局。orm
LayoutKind 枚舉 控制當導出到非託管代碼時對象的佈局。htm
成員名稱 | 說明 |
---|---|
Sequential | 對象的成員按照它們在被導出到非託管內存時出現的順序依次佈局。這些成員根據在 StructLayoutAttribute..::.Pack 中指定的封裝進行佈局,而且能夠是不連續的。 |
Explicit | 對象的各個成員在非託管內存中的精確位置被顯式控制。每一個成員必須使用 FieldOffsetAttribute 指示該字段在類型中的位置。 |
Auto | 運行庫自動爲非託管內存中的對象的成員選擇適當的佈局。使用此枚舉成員定義的對象不能在託管代碼的外部公開。嘗試這樣作將引起異常。 |
這就是控制對象轉化爲非託管代碼時佔用內存固定,這樣咱們就能夠舒服的使用Marshal.SizeOf方法了。獲得一個對象的大小。若是一個對象中還包含另一個對象,那麼另一個對象可使用這個[StructLayout(LayoutKind.Sequential)]也能夠不使用,若是使用則是,該對象的大小加上這個對象的大小;若是不使用則是該對象的大小加上4個字節(就是這個對象引用大小)。對象
當想獲取一個集合的大小時候,咱們不能在List上加這個屬性,由於微軟的dll中的類,那麼咱們怎麼樣才能獲取對應的大小呢?其實還用一種簡單的方式,就是將對象或者集合轉化成內存流,再獲取內存流的大小就ok了,雖然有一些其餘影響大小,但基本上能夠正確的粗略估計一個對象在內存的大小或者比較倆個對象、集合的大小的!blog
主要代碼:ip
BinaryFormatter binaryFormatter = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); binaryFormatter.Serialize(stream, personList); stream.Seek(0, SeekOrigin.Begin);
其實裏面東西多着的,我僅僅瞭解了一點點,分享一下,你們一塊兒討論一下,若是有錯誤,請批評指出!