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

原文地址:https://www.cnblogs.com/xdot/p/10089813.html

时间: 2024-10-05 06:17:44

C# 获取对象 大小 Marshal.SizeOf (sizeof 只能在不安全的上下文中使用)的相关文章

Java - 如何获取对象大小

有没有一种简单的方法获取特定对象的大小? 于是发现了这么个东西: 光看了下该方法的声明,这不就是获取对象的大小么,于是没想太多,心想这下问题变得简单了,弄了个premain方法初始化Instrumentation:     public class ObjectSizeUtils {     private static Instrumentation inst = null;     public static void premain(String agentArgs, Instrument

c/c++ sizeof运算符详解以及对象大小

原文:http://krystism.is-programmer.com/posts/41468.html 学过c的都知道sizeof运算符.不过还是需要注意以下几点.先从c的sizeof说起: 1. sizeof 是运算符,而不是函数.虽然我们习惯sizeof(...),但( )并不是必需的,它只是表示优先级.我们把sizeof后面的目标叫对象或者操作数.本文约定就叫sizeof对象. 2. 当sizeof 的对象是表达式时,求的大小是表达式返回值的类型大小,但并不计算表达式的值,比如 ? 1

(转)JS获取当前对象大小以及屏幕分辨率等

原文 JS获取当前对象大小以及屏幕分辨率等 <script type="text/javascript">function getInfo(){      var s = "";         s += " 网页可见区域宽:"+ document.body.clientWidth+"\n";          s += " 网页可见区域高:"+ document.body.clientHeig

聊聊JVM(三)两种计算Java对象大小的方法

这篇说说如何计算Java对象大小的方法.之前在聊聊高并发(四)Java对象的表示模型和运行时内存表示 这篇中已经说了Java对象的内存表示模型是Oop-Klass模型. 普通对象的结构如下,按64位机器的长度计算 1. 对象头(_mark), 8个字节 2. Oop指针,如果是32G内存以下的,默认开启对象指针压缩,4个字节 3. 数据区 4.Padding(内存对齐),按照8的倍数对齐 数组对象结构是 1. 对象头(_mark), 8个字节 2. Oop指针,如果是32G内存以下的,默认开启对

谈谈对象大小——从字节对齐到对象模型

谈谈对象大小——从字节对齐到对象模型 一. 前言         这篇文章主要介绍以下从c的结构体变量到c++的类对象中编译器对内存分配做的事情.总而言之,言而总之,这篇文章就是讲述对于一个变量(对象)它的内存布局是怎么样子的.         为了方便描述,我们按照以下几个层次来讲述:                 1.c中struct的字节对齐                 2.从struct到class的过渡                 3.单继承对对象内存模型的影响       

Qt之美(一):d指针/p指针详解(解释二进制兼容,以及没有D指针就会崩溃的例子。有了D指针,所使用的对象大小永远不会改变,它就是该指针的大小。这个指针就被称作D指针)good

Translated  by  mznewfacer   2011.11.16 首先,看了Xizhi Zhu 的这篇Qt之美(一):D指针/私有实现,对于很多批评不美的同路人,暂且不去评论,只是想支持一下Xizhi Zhu,在引用一下Jerry Sun的话,“C++需要宏定义就像需要设计模式一样.也许你不知道,宏是图灵完全(turing complete)的,至少LISP下是这样,C/C++需要宏,几乎所有重要的C/C++库都需要和依赖宏.这些都超过咱们的想象,宏能带给我们所谓语法糖(Synta

python动态获取对象的属性和方法

http://blog.csdn.net/kenkywu/article/details/6822220首先通过一个例子来看一下本文中可能用到的对象和相关概念.01     #coding: UTF-802     import sys #  模块,sys指向这个模块对象03     import inspect04     def foo(): pass # 函数,foo指向这个函数对象05      06     class Cat(object): # 类,Cat指向这个类对象07    

python动态获取对象的属性和方法 (转载)

首先通过一个例子来看一下本文中可能用到的对象和相关概念. #coding:utf-8 import sys def foo():pass class Cat(object): def __init__(self, name='Kitty'): self.name = name def sayHi(self): print self.name, 'says Hi!' cat = Cat() print Cat.sayHi print cat.sayHi 有时候我们会碰到这样的需求,需要执行对象的某

document获取对象三方法

Document对象中有几个常用的方法,我们在Dom简介中提到过.说到获取javascript对象的方法,最常用的可能就是getElementById了,它是Document中最常用的获取对象的方式之一,另外还有两个常用的获取对象的方法是getElementsByTagName 和getElementsByName.其中getElementById获取到的是单对象,而getElementsByName和 getElementsByTagName 获取到的都是集合. 现在我们有一个form表单,内