C# 可否獲取一個對象所佔內存的大小?
今日,在項目重構的時候突然想到一個問題,一個類哪些成員的增長,會影響一個類所佔內存的大小?C#有沒有辦法知道一個對象佔多少內存呢?安全
第一個問題:很快想到是類的非靜態的字段、屬性。 第二個問題:首先想到的是sizeof()。
下面開始驗證,首先來驗證值類型,驗證代碼以下:佈局
int size = sizeof (int); //4個字節
注意點:sizeof 運算符僅適用於值類型,而不適用於引用類型。sizeof 運算符只能在不安全代碼塊中使用。以下面的代碼將沒法編譯經過:code
public struct TestStuct
{orm
}
int size = sizeof(new TestStuct());
編譯後,提示:對象
錯誤 1 「ConsoleApplication3.TestStuct」沒有預約義的大小,所以 sizeof 只能在不安全的上下文中使用(請考慮使用 System.Runtime.InteropServices.Marshal.SizeOf) 內存
修改成Marshal.SizeOf方法,改方法返回對象的非託管大小(以字節爲單位)。參數能夠是引用類型或裝箱的值類型。佈局必須是連續的或顯式的。字符串
int size = Marshal.SizeOf(new TestStuct()); //1個字節
接下來來驗證引用類型:it
因爲不能做爲非託管結構進行封送處理;沒法計算有意義的大小或偏移量。全部下面的代碼在運行的時候,會拋出異常。io
public class Student
{
}編譯
int size = Marshal.SizeOf(new Student());
須要給Student類,加上一個StructLayoutAttribute,來控制Student類的數據字段的物理佈局。修改代碼爲:
[StructLayout(LayoutKind.Sequential)]
public class Student
{
}
int size = Marshal.SizeOf(new Student()); //1個字節
LayoutKind 默認值爲Auto.
結論:
1:對於託管對象是沒有辦法直接獲取到一個對象所佔的內存大小。
2:非託管對象,能夠使用Marshal.SizeOf
3:對內置類型,如int,long,byte等使用sizeof
擴展:
有人提出使用二進制序列化,將一個對象序列化成一個MemoryStream,而後返回MemoryStream.Length,通過驗證是不能夠的。
驗證代碼以下:
複製代碼
[Serializable]
public class Student
{
}
private static long GetObjectSize(object o)
{
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, o);
using (var fileStream = new FileStream(@"D:\Student.txt", FileMode.OpenOrCreate, FileAccess.Write))
{
var buffer = stream.ToArray();
fileStream.Write(buffer, 0, buffer.Length);
fileStream.Flush();
}
return stream.Length; } }
var student = new Student(); long size = GetObjectSize(student); //139個字節 複製代碼 Student.txt保存的文本信息以下所示,經過文本信息,能夠得知多出來的100多個字節,估計是就是這一串字符串吧