C# 获取对象 大小 Marshal.SizeOf (sizeof 只能在不安全的上下文中使用)
C# 能否獲取一個對象所占內(nèi)存的大小?
今日,在項(xiàng)目重構(gòu)的時候忽然想到一個問題,一個類哪些成員的增加,會影響一個類所占內(nèi)存的大小?C#有沒有辦法知道一個對象占多少內(nèi)存呢?
下面開始驗(yàn)證,首先來驗(yàn)證值類型,驗(yàn)證代碼如下:
int size = sizeof (int); //4個字節(jié)
注意點(diǎn):sizeof 運(yùn)算符僅適用于值類型,而不適用于引用類型。sizeof 運(yùn)算符只能在不安全代碼塊中使用。如下面的代碼將無法編譯通過:
public struct TestStuct
{
int size = sizeof(new TestStuct());
編譯后,提示:
錯誤 1 “ConsoleApplication3.TestStuct”沒有預(yù)定義的大小,因此 sizeof 只能在不安全的上下文中使用(請考慮使用 System.Runtime.InteropServices.Marshal.SizeOf)
修改為Marshal.SizeOf方法,改方法返回對象的非托管大小(以字節(jié)為單位)。參數(shù)可以是引用類型或裝箱的值類型。布局必須是連續(xù)的或顯式的。
int size = Marshal.SizeOf(new TestStuct()); //1個字節(jié)
接下來來驗(yàn)證引用類型:
由于不能作為非托管結(jié)構(gòu)進(jìn)行封送處理;無法計算有意義的大小或偏移量。所有下面的代碼在運(yùn)行的時候,會拋出異常。
public class Student
{
}
int size = Marshal.SizeOf(new Student());
需要給Student類,加上一個StructLayoutAttribute,來控制Student類的數(shù)據(jù)字段的物理布局。修改代碼為:
[StructLayout(LayoutKind.Sequential)]
public class Student
{
}
int size = Marshal.SizeOf(new Student()); //1個字節(jié)
LayoutKind 默認(rèn)值為Auto.
結(jié)論:
1:對于托管對象是沒有辦法直接獲取到一個對象所占的內(nèi)存大小。
2:非托管對象,可以使用Marshal.SizeOf
3:對內(nèi)置類型,如int,long,byte等使用sizeof
擴(kuò)展:
有人提出使用二進(jìn)制序列化,將一個對象序列化成一個MemoryStream,然后返回MemoryStream.Length,經(jīng)過驗(yàn)證是不可以的。
驗(yàn)證代碼如下:
復(fù)制代碼
[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();
}
var student = new Student();
long size = GetObjectSize(student); //139個字節(jié)
復(fù)制代碼
Student.txt保存的文本信息如下所示,通過文本信息,可以得知多出來的100多個字節(jié),估計是就是這一串字符串吧
轉(zhuǎn)載于:https://www.cnblogs.com/xdot/p/10089813.html
總結(jié)
以上是生活随笔為你收集整理的C# 获取对象 大小 Marshal.SizeOf (sizeof 只能在不安全的上下文中使用)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 后羿铭文怎么搭配最强(王者后羿最强铭文搭
- 下一篇: 雷林鹏分享:C# 运算符