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

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

 第二个问题:首先想到的是sizeof()。

下面开始验证,首先来验证值类型,验证代码如下:

int size = sizeof (int); //4个字节
注意点:sizeof 运算符仅适用于值类型,而不适用于引用类型。sizeof 运算符只能在不安全代码块中使用。如下面的代码将无法编译通过:

public struct TestStuct
{

}

int size = sizeof(new TestStuct());
编译后,提示:

错误 1 “ConsoleApplication3.TestStuct”没有预定义的大小,因此 sizeof 只能在不安全的上下文中使用(请考虑使用 System.Runtime.InteropServices.Marshal.SizeOf)

修改为Marshal.SizeOf方法,改方法返回对象的非托管大小(以字节为单位)。参数可以是引用类型或装箱的值类型。布局必须是连续的或显式的。

int size = Marshal.SizeOf(new TestStuct()); //1个字节
接下来来验证引用类型:

由于不能作为非托管结构进行封送处理;无法计算有意义的大小或偏移量。所有下面的代码在运行的时候,会抛出异常。

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

最新文章

  1. [转]Linux系统中‘dmesg’命令处理故障和收集系统信息的7种用法
  2. [整理]AngularJS学习资源
  3. EmguCV学习 与opencv的区别和联系
  4. DNS(三)DNS SEC(域名系统安全扩展)
  5. android _scrollview嵌套listview出现高度显示不全解决方案
  6. HTML5中类jQuery选择器querySelector的高级使用 document.querySelectorAll.bind(document);
  7. SqlServer varchar数据中类似于1.1.1.1这种值的排序方法
  8. java Mac自动化-java和ant环境搭建
  9. Javascript与C#对变量的处理方式
  10. MailUtils类:用于发送激活邮件
  11. 浅析 Bag of Feature
  12. nginx default_server的作用
  13. C++11多线程教学
  14. maven 编译解决jdk 版本问题
  15. hash(2018年CSUST省赛选拔赛第一场B题+hash+字典树)
  16. svn服务器搭建及使用 二
  17. 伪元素改变date类型input框的默认样式实例页面
  18. Laxcus大数据分布计算演示实例
  19. java程序——随机数求和
  20. TestNG测试执行顺序

热门文章

  1. ACM知识点总结
  2. [P1441]砝码称重 (搜索+DP)
  3. [P1879][USACO06NOV]玉米田Corn Fields (状态压缩)
  4. Python二进制转十进制算法、十进转二进制算法
  5. PLC STL any数据类型
  6. JAVA自学笔记25
  7. jQuery 学习02——效果:隐藏/显示、淡入淡出、滑动、动画、停止动画、Callback、链
  8. set non-stop on
  9. sqlserver数据库出现可疑错误修复方法
  10. EBS WEBADI 下载模板提示 Visual Basic 运行时错误 '91' 对象变量或With块变量未设置