程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> .NET對象占內存多少

.NET對象占內存多少

編輯:C#入門知識

一直有一個小小的疑惑——.NET一個對象或者一個集合占多少內存?有沒有很快速的方法獲取,而不是簡單的估計分析對象大小?

查了MSDN,和一些其他人的分析,得到解決是托管代碼對象的大小無法真實的得到,因為存在托管對象轉化成非托管的CLR優化。但我仍然不死心,非要弄個究竟!好吧,最終得到一些結果了。

 sizeof關鍵字,用於獲取值類型的大小,如int(占4個字節),char(2個字節);並且sizeof 運算符僅適用於值類型,而不適用於引用類型。所以針對對象改關鍵字無法使用。

查閱msdn,發現對象Marshal.SizeOf 方法,解釋為返回類的非托管大小;但是仍然不能使用,因為針對的是非托管代碼,如果直接使用一個類的對象,會報一個錯誤:"不能作為非托管結構進行封送處理;無法計算有意義的大小或偏移量。";這是因為對象在內存中實際大小並不是固定的,可能這次運行一個值,下次就是另外一個值了,存在優化!

所以為了固定一個對象的大小,必須告訴CLR不優化對象在內存中的大小。這就需要在聲明類的時候加上[StructLayout(LayoutKind.Sequential)]這個特性;

StructLayoutAttribute 類使用戶可以控制類或結構的數據字段的物理布局。

LayoutKind 枚舉  控制當導出到非托管代碼時對象的布局。

成員名稱說明 Sequential 對象的成員按照它們在被導出到非托管內存時出現的順序依次布局。這些成員根據在 StructLayoutAttribute..::.Pack 中指定的封裝進行布局,並且可以是不連續的。 Explicit 對象的各個成員在非托管內存中的精確位置被顯式控制。每個成員必須使用 FieldOffsetAttribute 指示該字段在類型中的位置。 Auto 運行庫自動為非托管內存中的對象的成員選擇適當的布局。使用此枚舉成員定義的對象不能在托管代碼的外部公開。嘗試這樣做將引發異常。

這就是控制對象轉化為非托管代碼時占用內存固定,這樣我們就可以舒服的使用Marshal.SizeOf方法了。得到一個對象的大小。如果一個對象中還包含另外一個對象,那麼另外一個對象可以使用這個[StructLayout(LayoutKind.Sequential)]也可以不使用,如果使用則是,該對象的大小加上這個對象的大小;如果不使用則是該對象的大小加上4個字節(就是這個對象引用大小)。

當想獲取一個集合的大小時候,我們不能在List上加這個屬性,因為微軟的dll中的類,那麼我們怎麼樣才能獲取對應的大小呢?其實還用一種簡單的方式,就是將對象或者集合轉化成內存流,再獲取內存流的大小就ok了,雖然有一些其他影響大小,但基本上可以正確的粗略估計一個對象在內存的大小或者比較倆個對象、集合的大小的!

主要代碼:

BinaryFormatter binaryFormatter = = , SeekOrigin.Begin);

其實裡面東西多著的,我僅僅了解了一點點,分享一下,大家一起討論一下,如果有錯誤,請批評指出!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved