C#计算对象占用内存大小(.net)
我们写了很多的代码,但是有没有想过每写一句代码会占用多大空间呢,现在就来算一下。
一.对象大小
影响对象占用多大空间的主要因素如下:
1:字段个数
2:字段类型
3:字段布局
二.字段类型
先来看一下,主要数据类型在32位系统和64位系统中的字节长度:
从上面可以得知只有指针类型变成了8个字节,因为指针里面存储的是数据的地址,而非数据本身,所以会变为2倍。
三.布局
在clr中,布局一共有三种:
1:LayoutKind.Auto:clr会优化字段排序。
2:LayoutKind. Sequential :clr不会优化字段排序,按照代码顺序进行布局。
3:LayoutKind. Explicit:每个字段必须设置FieldOffset,来决定字段的布局。
四.预测对象占用的空间
根据LayoutKind的设置,布局会有所不同,以下都是以32位操作系统为例:
1:PeopleAuto类采用LayoutKind.Auto布局,clr会优化字段排序,将两个bool行的字段放到了后面,不够就补齐四个字节,外加同步块索引和类型对象指针,所以一共占20个字节。
2:PeopleSequential类采用LayoutKind. Sequential布局,clr不会优化字段排序,按照代码顺序进行布局,不够就补齐四个字节,外加同步块索引和类型对象指针,所以一共占24个字节。
3:PeopleExplicit类采用LayoutKind. Explicit:每个字段必须设置FieldOffset,来决定字段的布局,不够就补齐四个字节。由于三个字段的FieldOffset都设置为0,外加同步块索引和类型对象指针,所以一共占16个字节。
五.验证对象占用的空间
1:PeopleAuto类:通过windbg查看,PeopleAuto占用的空间为20byte,和理论值一样,布局也和预测的一样,如下:
2:PeopleSequential类:通过windbg查看, PeopleSequential只占用了空间为20byte,和理论值(24byte)不一样,布局也不一样。Clr还是做了优化。(这里还是需要做进一步的研究)
3:PeopleExplicit类:通过windbg查看, PeopleExplicit占用的空间为16byte,和理论值一样。布局也和预测的一样。
六.总结
1:32位操作系统和64位操作系统,只有指针的长度从4byte变成了8byte,其他类型字段没有区别。
2:字段个数、字段类型和布局决定对象占用空间大小。
3: LayoutKind.Auto: clr会优化字段排序。
4: LayoutKind. Sequential: 按照代码顺序进行布局。(如果优化能起到减小空间的话,那还是会优化的,还需要进一步研究)
5: Layo4utKind. Explicit:通过指定字段的布局来控制字段大小,从而改变默认布局。
6:字段字节过小,会发生字段补齐,占满4或8个字节。