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如此- 这应该怎么选择呢?它必须准确!!
根据这个样本,他们不考虑填充,他们应该...(或不...)
这看起来可能是不诚实的 - 但是从内存映射文件的角度来看,您感兴趣的大小与内存中该对象的大小不同.它们可能被称为内存映射文件,但在.Net中并不一定意味着与本机代码完全相同. (但是底层实现仍然是相同的 - 逻辑内存的一部分映射到文件的一部分,因此名称仍然正确)
sizeof返回在物理内存中对象的正确尺寸,包括任何填充字节等,因此,如果您需要了解本机内存方面对象的确切大小,使用(但是这并不适用于内存映射文件,我稍后会解释一下).
正如文档Marshal.SizeOf所述,从.Net的角度报告对象的大小,不包括两个隐藏的数据项; 仅由运行时使用.
您复制的示例使用,Marshal.SizeOf因为填充值仅在内存中与物理对象相关.对象序列化后,只序列化逻辑 .Net数据.再次加载对象时,将根据该点的运行时状态重新分配这两个填充值.例如,类型指针可能不同.将它们序列化将毫无意义.这就像将一个本机指针(而不是一个偏移量)序列化到磁盘一样 - 下次指向的数据极不可能在同一个地方.
Ergo - 如果你想知道100个Color对象在物理内存中使用了多少- 使用sizeof; 如果你想知道相同数据的memroy映射文件有多大,请使用Marshal.SizeOf.