一直有一個小小的疑惑——.NET一個對象或者一個集合占多少內存?有沒有很快速的方法獲取,而不是簡單的估計分析對象大小?
查了MSDN,和一些其他人的分析,得到解決是托管代碼對象的大小無法真實的得到,因為存在托管對象轉化成非托管的CLR優化。但我仍然不死心,非要弄個究竟!好吧,最終得到一些結果了。
sizeof關鍵字,用於獲取值類型的大小,如int(占4個字節),char(2個字節);並且sizeof 運算符僅適用於值類型,而不適用於引用類型。所以針對對象改關鍵字無法使用。
查閱msdn,發現對象Marshal.SizeOf 方法,解釋為返回類的非托管大小;但是仍然不能使用,因為針對的是非托管代碼,如果直接使用一個類的對象,會報一個錯誤:"不能作為非托管結構進行封送處理;無法計算有意義的大小或偏移量。";這是因為對象在內存中實際大小並不是固定的,可能這次運行一個值,下次就是另外一個值了,存在優化!
所以為了固定一個對象的大小,必須告訴CLR不優化對象在內存中的大小。這就需要在聲明類的時候加上[StructLayout(LayoutKind.Sequential)]這個特性;
StructLayoutAttribute 類使用戶可以控制類或結構的數據字段的物理布局。
LayoutKind 枚舉 控制當導出到非托管代碼時對象的布局。
這就是控制對象轉化為非托管代碼時占用內存固定,這樣我們就可以舒服的使用Marshal.SizeOf方法了。得到一個對象的大小。如果一個對象中還包含另外一個對象,那麼另外一個對象可以使用這個[StructLayout(LayoutKind.Sequential)]也可以不使用,如果使用則是,該對象的大小加上這個對象的大小;如果不使用則是該對象的大小加上4個字節(就是這個對象引用大小)。
當想獲取一個集合的大小時候,我們不能在List上加這個屬性,因為微軟的dll中的類,那麼我們怎麼樣才能獲取對應的大小呢?其實還用一種簡單的方式,就是將對象或者集合轉化成內存流,再獲取內存流的大小就ok了,雖然有一些其他影響大小,但基本上可以正確的粗略估計一個對象在內存的大小或者比較倆個對象、集合的大小的!
主要代碼:
BinaryFormatter binaryFormatter = = , SeekOrigin.Begin);
其實裡面東西多著的,我僅僅了解了一點點,分享一下,大家一起討論一下,如果有錯誤,請批評指出!