我一直有一个小小的疑问:一个.NET对象或者集合占用了多少内存?有没有一种快速的方法来获取它,而不仅仅是估计和分析对象的大小?
我检查了MSDN等。别人分析的解决方案是,托管代码对象的大小并不能真正实现,因为有CLR优化将托管对象转换为非托管对象,但我还没有放弃,需要找出答案!好了,终于得到一些结果了
sizeof关键字用于获取像int(占用一个字节)char(占用一个字节)这样的值类型的大小;而sizeof运算符仅适用于值,不适用于类型,因此该关键字不能用于对象。
查看msdn,我发现对象的MarshalSizeOf方法被解释为返回类的非托管大小,但仍然;无法使用,因为它针对的是非托管代码。如果直接使用类的对象,会报错,无法作为非托管结构密封提交处理,无法计算重要维度或偏移量;内存中对象的大小不固定。有可能这次是一个值,下次会是另一个值。有一个优化!
因此,要固定对象的大小,必须告诉CLR优化内存中对象的大小。这就需要在声明类时添加[StructLayout(LayoutKindSequential)]函数;
StructLayoutAttribute类允许用户执行此操作。控制类或结构的数据字段的物理布局
LayoutKind枚举控制导出到非托管代码时对象的布局
成员名称描述顺序对象成员按以下顺序依次排列它们在导出到非托管存储时出现。这些成员根据StructLayoutAttribute::Pack中指定的包进行排列,并且可以是离散的。Explicit对象的各个成员排列在显式控制的非托管内存中。每个成员必须使用FieldOffsetAttribute来指示字段在类型中的位置。Auto运行时自动为非托管内存中的对象成员选择适当的布局。使用此枚举成员定义的对象不能在队列管理存储中使用。外部公共尝试这样做将导致异常这是控制对象转换为非托管代码时占用的内存。这样我们就可以方便的使用MarshalSizeOf方法来获取一个对象还包含另一个对象的大小,所以另外一个辉哲对象可以使用这个[StructLayout(LayoutKindSequential)]也可以不使用。如果使用的话,就是对象的大小加上这个对象的大小,如果不使用的话,就是对象的大小加上字节(即这个对象的引用的大小)
当我们想要获取集合的大小时,由于Microsoftdll中的类,我们无法将此属性添加到List中。那么,我们怎样才能得到对应的尺寸呢?其实有一个简单的方法:将对象或集合转换为内存流,然后获取内存流的大小。虽然还有一些其他作用,但基本上可以正确估计内存中对象的大小或者比较两个对象集合的大小!
主要代码
BinaryFormatterbinaryFormatter=newBinaryFormatter();
MemoryStreamstream=newMemoryStream();
binaryFormatterSerialize(streampersonList);
streamSeek(SeekOriginBegin);
lishixinzhi/Article/program/net/201311/13940上一篇:装了内存条蓝屏怎么办
下一篇:怎么让抖音不占用内存