【问题标题】:Why does valutype take less space than object type in .NET?为什么 .NET 中值类型占用的空间比对象类型少?
【发布时间】:2023-03-07 00:55:01
【问题描述】:

据说valuetype来源于system.object。为什么对象派生类比值类型结构占用更多空间? 在此先感谢

【问题讨论】:

  • It is said that valuetype derives from system.object. - 我想知道这是在哪里说的,如果你找到一些声称这一点的来源,我建议你避免将其作为学习材料。
  • @Darin - ValueType 确实派生自 System.Object : msdn.microsoft.com/en-us/library/…。然而,它和它的派生类型由 CLR 和编译器以特殊方式处理,因此它肯定不会像它那样行事......但正如参考资料所说,对象是一切的基础,我看到了发帖人的困惑(拳击是一个复杂的话题)
  • @Darin 你有没有声称相反的消息来源?我认为ValueType 在技术上源自Object,甚至本身就是一个引用类型。但当然,将任何具体值类型转换为ValueTypeObject 是一种装箱转换。
  • @Darin Dimitrov:你的意思是像MSDN

标签: .net cil value-type


【解决方案1】:

每个对象都有一个对象头。这在 32 位机器上是 8 个字节,4 个用于同步块,4 个用于类型句柄。值类型值仅在装箱时从 System.Object 派生。 int 拆箱时为 4 字节,装箱时为 12 字节,标头为 +8 字节。

查看this answer 以更深入地了解装箱值类型的外观。

【讨论】:

  • 值类型 always 派生自 Object,并且装箱值类型不会将其转换为对象,它仅存储在对象内部。装箱的 int 在 32 位系统上使用 16 个字节,在 64 位系统上使用 20 个字节。
  • @Guffa - 您可以使用链接的答案来查看这是不正确的。创建两个对象。
  • 这仅显示数据是如何存储的。装箱的值类型仍然是值类型,它没有获得对象的任何特征。像Point 这样的可变结构在装箱时不会成为可变对象,它仍然是存储在对象内部的结构。
  • @Guffa - 不知道你想表达什么观点。当您谈到盒装 int 的 16 字节的 size 时,那么它的 存储方式 非常重要。我假设您看到它在调试器的 GC 堆上占用了 12 个字节。是的,值类型位的布局与装箱时完全相同,在调试器中也可见。那里没有分歧。加上 8 字节的对象头。
【解决方案2】:

因为编译器对值类型的处理方式不同。尽管它们继承自 Object,但它们不会存储为对象。

对象存储在堆上,有两个指针的额外开销(32 位系统上为 8 个字节,64 位系统上为 16 个字节)。值类型是内联存储的,可以作为对象的一部分,也可以存储在方法调用的堆栈帧中,没有额外的开销。

【讨论】:

    【解决方案3】:

    关于从 ValueType 继承和从 Object 继承的值类型,大多数时候都有一些善意的谎言。未装箱的 int 或 bool 没有存储与该继承相关的任何内容。但是,如果它被装箱(这将在某些操作中隐式发生),它会获得它。大多数语言都隐藏了这一点,因此无论何时使用它们,它们看起来都与派生自 Object 的任何其他对象相同,但当我们使用它们时,它们也充当简单类型。

    【讨论】:

      猜你喜欢
      • 2023-01-03
      • 1970-01-01
      • 2014-03-12
      • 2021-08-25
      • 2021-07-08
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      相关资源
      最近更新 更多