C# 获取对象 大小 Marshal.SizeOf (sizeof 只能在不安全的上下文中使用)
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多个字节,估计是就是这一串字符串吧
C# 获取对象 大小 Marshal.SizeOf (sizeof 只能在不安全的上下文中使用)的更多相关文章
- c/c++ sizeof运算符详解以及对象大小
原文:http://krystism.is-programmer.com/posts/41468.html 学过c的都知道sizeof运算符.不过还是需要注意以下几点.先从c的sizeof说起: 1. ...
- c++ sizeof对象大小整理
1. sizeof 是运算符,而不是函数. 2. 当sizeof 的对象是表达式时,求的大小是表达式返回值的类型大小,但并不计算表达式的值,比如: ; ; cout << sizeof(c ...
- (转)JS获取当前对象大小以及屏幕分辨率等
原文 JS获取当前对象大小以及屏幕分辨率等 <script type="text/javascript">function getInfo(){ var ...
- JS获取当前对象大小以及屏幕分辨率等...
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <meta nam ...
- 【Javascript Demo】JS获取当前对象大小以及屏幕分辨率等
效果如下: 代码如下: <html> <head> <title>获取当前对象大小以及屏幕分辨率等</title> <body> <d ...
- 【NX二次开发】UF_OBJ_ask_display_properties获取对象所在层、获取对象颜色、获取对象是否隐藏、获取对象是否高亮,获取对象线宽、字体大小
UF_OBJ_ask_display_properties 返回一个对象的显示属性(层.颜色.隐藏状态.线宽和字体). UF_OBJ_disp_props_p_t结构体: layer int 对象所在 ...
- Java对象大小计算
这篇说说如何计算Java对象大小的方法.之前在聊聊高并发(四)Java对象的表示模型和运行时内存表示 这篇中已经说了Java对象的内存表示模型是Oop-Klass模型. 普通对象的结构如下,按64位机 ...
- Java虚拟机14:Java对象大小、对象内存布局及锁状态变化
一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...
- 通过runtime获取对象相关信息
通过runtime获取对象相关信息 在这里,本人给大家提供一个runtime关于NSObject的扩展,用来显示各种NSObject中的信息,这有助于你来分析类的组成:) 先准备以下类供测试: Mod ...
随机推荐
- 使用ssm框架实现简单网页注册功能
1.注册Spring配置文件,在web应用启动时创建Spring容器(注册listener). <!-- 注册spring配置文件 --> <context-param> &l ...
- SpringMVC的请求处理流程
- Linux vi/vim命令高效助记图
图片来源网上,如有侵权,请告知,我会删除掉,谢谢~ 常用编辑按键: 1 vi +[num] file 打开文件,并将光标置于第n行首 2 vi + file 打开文件,并将光标置于最后一行首 3 vi ...
- eclipse编辑环境下导入springmvc的源码
如果想要查看@ModelAttribute的源码,只需要,点击ctrl+鼠标左键,就会出现attach--,点击attach--,external,选择类似springframe-web-source ...
- function前加运算符实现立即执行函数
我们知道函数的调用方式通常是FunctionName() 但如果我们尝试为一个"定义函数"末尾加上(),解析器是无法理解的. function msg(){ alert('mess ...
- 面试必备:HashMap、Hashtable、ConcurrentHashMap的原理与区别
同步首发:http://www.yuanrengu.com/index.php/2017-01-17.html 如果你去面试,面试官不问你这个问题,你来找我^_^ 下面直接来干货,先说这三个Map的区 ...
- chrome浏览器美化插件:让您的浏览器页面冒水泡, 游小鱼儿
下载插件和效果图 这是一个让你的浏览器冒泡泡的插件, 浏览网页的时候仿佛置身于海底世界: 插件下载地址:http://files.cnblogs.com/files/diligenceday/chro ...
- angular 2 - 001 ng cli的安装和使用
angular cli 创建项目和组件 ng new my-app --skip-install cd my-app cnpm install ng serve localhost:4200 angu ...
- 天府大讲堂:5G时代的物联网发展趋势与产业变革
摘要:国家973物联网首席科学家,中科院上海微系统与信息技术研究所副所长,无锡物联网产业研究院院长刘海涛教授讲授的5G时代的物联网发展趋势与产业变革意义深刻.作者根据天府大讲堂听讲内容加工整理所得,旨 ...
- Linux命令行烧录树莓派镜像至SD卡
首先下载镜像压缩包 验证压缩包的未被串改 1 sha1sum 2013-09-25-wheezy-raspbian.zip 对此命令的输出结果和官网给出的SHA-1 Checksum进行比对,如果一致 ...