# C# 能否获取一个对象所占内存的大小？

今日，在项目重构的时候忽然想到一个问题，一个类哪些成员的增加，会影响一个类所占内存的大小？C#有没有办法知道一个对象占多少内存呢？

第一个问题：很快想到是类的非静态的字段、属性。

第二个问题：首先想到的是sizeof（）。

int size = sizeof (int); //4个字节

public struct TestStuct
{

}

int size = sizeof(new TestStuct());

int size = Marshal.SizeOf(new TestStuct()); //1个字节

 public class Student
{
}

int size = Marshal.SizeOf(new 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

[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多个字节，估计是就是这一串字符串吧。

              JConsoleApplication3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null   ConsoleApplication3.Student    

延伸阅读：http://blogs.msdn.com/b/cbrumme/archive/2003/04/15/51326.aspx原文如下：

We don't expose the managed size of objects because we want to reserve the ability to change the way we lay these things out.  For example, on some systems we might align and pack differently.  For this to happen, you need to specify tdAutoLayout for the layout mask of your ValueType or Class.  If you specify tdExplicitLayout or tdSequentialLayout, the CLR’s freedom to optimize your layout is constrained.

If you are curious to know how big an object happens to be, there are a variety of ways to discover this. You can look in the debugger.  For example, Strike or SOS (son-of-strike) shows you how objects are laid out.  Or you could allocate two objects and then use unverifiable operations to subtract the addresses. 99.9% of the time, the two objects will be adjacent.  You can also use a managed profiler to get a sense of how much memory is consumed by instances of a particular type.

But we don't want to provide an API, because then you could form a dependency over this implementation detail.

Some people have confused the System.Runtime.InteropServices.Marshal.SizeOf() service with this API. However, Marshal.SizeOf reveals the size of an object after it has been marshaled.  In other words, it yields the size of the object when converted to an unmanaged representation.  These sizes will certainly differ if the CLR’s loader has re-ordered small fields so they can be packed together on a tdAutoLayout type.

posted @ 2013-05-16 16:19  supperwu  阅读(32469)  评论(11编辑  收藏  举报