.NET中自定义结构类型的内存开销是多少?有一个与.NET对象相关的固定开销,这个问题对此有更全面的概述:Thememoryoverheadof.NETobjectsis12or24bytes,dependingonyouareina32or64bitprocess。也就是说,像int、double、boolean等原始值类型不会产生开销,因为它们是值类型。您将自定义结构类型放在应用程序的什么位置?一方面,它们是值类型,如上面的int、double、boolean[因此应该没有开销],但另一方面它们是间接派生自System.Object,因此(技术上)应该有开销。您将自定义结构类型放在应用程序的什么位置?它们与原始类型没有什么不同。除了他们拥有的字段之外,他们不会施加额外的开销。它们派生自对象这一事实并不意味着它们会产生引用类型所带来的开销,即方法表指针和同步根块。您可以使用Marshal.SizeOf进行测试:voidMain(){varf=newFoo();Console.WriteLine(Marshal.SizeOf(f));}publicstructFoo{publicintX{get;放;}publicintY{得到;放;这将在32位模式下打印8,它恰好是两个整数值(每个4个字节)。请注意,Marshal.SizeOf将输出非托管对象的大小。CLR仍然可以自由地重新排序字段或将它们打包在一起。结构的大小由其字段大小加上正确对齐的字段之间的填充,加上结构末尾的填充以确保在存储结构时它们仍然是正确对齐的数组来确定。因此,一方面,结构包含引用类型的字段并非完全不可能。像一个字符串。在这种情况下,结构体会更大,因为引用实际上是一个指针,需要8个字节而不是4个字节。填充是一个更巧妙的细节。在32位模式下,变量不能指向比4更好的对齐方式。双精度和长型,8字节类型很容易错位。尤其是影响32位程序的性能,如果double错位在L1缓存边界线上,读取或写入速度可能是3倍。这也是为什么这些类型在C#内存模型中不是原语的核心原因。在64位模式下不是问题,CLR必须并且确实提供了8的对齐保证。但是,CLR确实尝试在32位模式下正确对齐此类结构成员,即使结构本身不能保证对齐。否则,结构副作用具有隐式[StructLayout(LayoutKind.Sequential,Pack=8)]属性。CLR源代码中的一个奇怪之处是没有注释执行此操作的C++语句。我怀疑它是否能快速解决非托管互操作性能不佳的问题,保持结构可复制对于提高速度很重要。但是,如果结构包含的成员本身就是没有顺序布局的结构,则CLR会放弃。值得注意的是,DateTime和DateTimeOffset会发生这种情况,编写它们的程序员出于非常神秘的原因向其应用了[StructLayout(LayoutKind.Auto)]属性。对于DateTimeOffset,可能是复制/粘贴错误。结构的布局现在将不可预测,它也变成LayoutKind.Auto,CLR重新排列字段以最小化结构的大小。这可能会在x64模式下导致额外的填充。这些是您永远不应该担心的晦涩的实现细节。字段对齐可能有一些开销:https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute(v=vs.100).aspx例如publicstructTest{publicByteA;公长B;}在64位进程上大小为16字节,在32位进程上相应为12字节(当时我们只能期望9字节);零。除非由于对齐而存在间隙,否则这就是这些间隙的成本。但除此之外,结构就像字段是放置在堆栈上的独立变量。虽然它是盒子,但您可以通过对象来处理它,它与任何其他引用类型具有相同的开销。以上是C#学习教程:.NET自定义结构类型的内存开销是多少?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
