当前位置: 首页 > 编程语言 > C#

CLR顺序结构布局:对齐和大小共享

时间:2023-04-11 00:47:11 C#

CLR顺序结构布局:对齐和大小默认情况下,C#中的所有结构都被视为带有[StructLayout(LayoutKind.Sequential)]标记的值类型。所以让我们获取一些struct并检查这个struct的大小:usingSystem;使用System.Reflection;使用System.Linq;使用System.Runtime.InteropServices;classFoo{structE{}structS0{bytea;}structS1{字节a;字节b;}structS2{字节a;字节b;字节c;}structS3{bytea;诠释乙;}structS4{inta;字节b;}structS5{字节a;字节b;诠释c;}structS6{字节a;诠释乙;字节c;}structS7{inta;字节b;诠释c;}structS8{字节a;短b;诠释c;}structS9{短一个;字节b;诠释c;}structS10{长一个;字节b;}structS11{bytea;长b;}structS12{bytea;字节b;短c;短d;龙e;}structS13{Ea;Eb;}structS14{Ea;Eb;诠释c;}structS15{bytea;字节b;字节c;字节d;字节e;}结构S16{S15b;字节c;}structS17{长一个;S15b;}structS18{长一个;S15b;S15c;}structS19{长一个;S15b;S15c;Ed;短e;}structS20{长一个;S15b;S15c;短d;Ee;}staticvoidMain(){Console.WriteLine("name:contents=>sizen");foreach(vartypeintypeof(Foo).GetNestedTypes(BindingFlags.NonPublic)){varfields=type.GetFields(BindingFlags.NonPublic|BindingFlags.Instance);Console.WriteLine("{0}:{2}=>{1}",type.Name,Marshal.SizeOf(type),string.Join("+",fields.Select(_=>Marshal.SizeOf(_.FieldType))));}}}输出是(在x86/x64上相同):name:contents=>sizeE:=>1S0:1=>1S1:1+1=>2S2:1+1+1=>3S3:1+4=>8S4:4+1=>8S5:1+1+4=>8S6:1+4+1=>12S7:4+1+4=>12S8:1+2+4=>8S9:2+1+4=>8S10:8+1=>16S11:1+8=>16S12:1+1+2+2+8=>16S13:1+1=>2S14:1+1+4=>8S15:1+1+1+1+1=>5S16:5+1=>6S17:8+5=>16S18:8+5+5=>24S19:8+5+5+1+2=>24S20:8+5+5+2+1=>24看这个结果我无法理解用于顺序结构的布局(字段对齐和totalsize)RulesetCLR有人可以解释这种行为吗?所有字段都根据它们的类型对齐。本机类型(int、byte等)都根据它们的大小对齐。例如,一个int将始终是4个字节的倍数,而一个Thebyte可以是任何地方。如果较小的字段位于int之前,则将在必要时添加填充以确保int正确对齐到4个字节。这就是为什么S5(1+1+4=8)和S8(1+2+4=8)会有填充并且最终大小相同:[1][1][][][4]//S5[1][][2][4]//S8此外,结构本身继承了其最对齐字段的对齐方式(即,对于S5和S8,int是最对齐的字段,因此它们的对齐方式均为4).对齐是继承的,这样当你有一个结构数组时,所有结构中的所有字段都将正确对齐。所以,4+2=8。[4][2][][]//从0开始[4][2][][]//从8[4][2][][]//开始从16开始请注意,4始终是对齐方式4。如果您不继承最对齐的字段,则数组中的每个其他元素都有一个对齐到6字节而不是4的int:[4][2]//从0开始[4][2]//从6开始——[4]没有正确对齐![4][2]//从12开始这将非常糟糕,因为并非所有体系结构都允许从未对齐的内存地址读取,即使是那些具有(可能非常大,如果在缓存行或页面边界上)性能损失的内存地址这样做。除了基本性能之外,对齐还可以实现并发。C#内存模型保证最大4字节宽的本机类型的读/写是原始的,而.NET具有像Interlocked类这样的原始类型。像这样的原语操作归结为CPU指令本身需要对齐的内存访问才能工作。正确对齐非常重要!您经常会看到聪明的本机编码人员在设计结构时考虑到所有这些,将所有字段从大到小排序,以便将填充和结构大小保持在最小值。以上就是C#学习教程:CLR顺序结构布局:对齐和大小共享。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。涉及侵权,请点击维权联系管理员删除。如需转载请注明出处: