.net对象大小填充?

Roy*_*mir 9 .net c# clr .net-4.0

msdn

sizeof运算符只能用于不安全的代码块.虽然您可以使用Marshal.SizeOf方法,但此方法返回的值并不总是与sizeof返回的值相同.

Marshal.SizeOf在类型被封送后返回大小,而sizeof返回公共语言运行时分配的大小,包括任何**填充**.

我读过这本书:c#via clr(第522页)

那: 在此输入图像描述

问题:

1)这里提到的填充:

在此输入图像描述

和书中提到的一样吗?

2)如果我有对象类型Person- 我怎么知道它在记忆中的真实大小

编辑 - 为什么我需要它?

请注意这个:

他们有阅读记录样本:

 using (var accessor = mmf.CreateViewAccessor(offset, length))
            {

                int colorSize = Marshal.SizeOf(typeof(MyColor)); //<--------HERE
                MyColor color;


                for (long i = 0; i < length; i += colorSize)
                {
                    accessor.Read(i, out color);
                    color.Brighten(10);
                    accessor.Write(i, ref color);
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

如果所报告的尺寸由MARSHAL.sizeOF不是该尺寸sizeOF如此- 应该怎么选择呢?它必须准确!!

根据这个样本,他们不考虑填充,他们应该...(或不...)

And*_*tan 5

这看起来可能是不诚实的 - 但是从内存映射文件的角度来看,您感兴趣的大小与内存中该对象的大小不同.它们可能被称为内存映射文件,但在.Net中并不一定意味着本机代码完全相同. (但是底层实现仍然是相同的 - 逻辑内存的一部分映射到文件的一部分,因此名称仍然正确)

sizeof返回在物理内存中对象的正确尺寸,包括任何填充字节等,因此,如果您需要了解本机内存方面对象的确切大小,使用(但是这并不适用于内存映射文件,我稍后会解释一下).

正如文档Marshal.SizeOf所述,从.Net的角度报告对象的大小,不包括两个隐藏的数据项; 仅由运行时使用.

您复制的示例使用,Marshal.SizeOf因为填充值仅在内存中与物理对象相关.对象序列化后,只序列化逻辑 .Net数据.再次加载对象时,将根据该点的运行时状态重新分配这两个填充值.例如,类型指针可能不同.将它们序列化将毫无意义.这就像将一个本机指针(而不是一个偏移量)序列化到磁盘一样 - 下次指向的数据极不可能在同一个地方.

Ergo - 如果你想知道100个Color对象在物理内存中使用了多少- 使用sizeof; 如果你想知道相同数据的memroy映射文件有多大,请使用Marshal.SizeOf.