【问题标题】:Why does System.Int32 take 24 bytes?为什么 System.Int32 占用 24 个字节?
【发布时间】:2022-07-06 07:03:33
【问题描述】:

如果 int 占用 4 个字节,为什么 System.Int32 在将整数装箱到对象时占用 24 个字节?

例如:

int i = 3;
object o = i;

【问题讨论】:

  • 究竟如何你是怎么得到这些数字的?
  • 我很好奇你是如何测量你的 24 字节的(你没有显示出来)。名称 o 是一个对象变量(即对引用类型实例的引用),因此它所引用的对象(装箱的 int)被分配在托管堆上,o 最终成为一个引用类型变量,持有对该对象的引用
  • “装箱”是指将值类型放入对象框中。它不仅仅是一个演员表:它有效地添加了一个指针和其他与拥有完整对象引用有关的陷阱。换句话说,盒子本身有一些开销。
  • 你是用这种措辞区分intSystem.Int32吗?

标签: c# .net boxing


【解决方案1】:

在 C#/CLR 中,引用类型有 some size overhead:

托管对象的布局非常简单:托管对象包含实例数据、指向元数据的指针(也称为方法表指针)和一包内部信息,也称为对象头。

因此,当您将 int 装箱到堆中时,它将作为引用类型存储并包含所有额外信息,然后内存将被对齐,从而产生如下结果:

Object Header (8 bytes)
Method Table Pointer (8 bytes)
Int (4 bytes)
padding (4 bytes, to align at 8 bytes)

请注意,这取决于进程的位数(上面的细分是针对 64 位的情况)并且实际上是运行时实现细节(之前链接的文章提到了至少一个实现 differs)。

【讨论】:

  • 正确,但它确实是运行时的实现细节。您知道装箱的值将有一个标题等,但该标题到底有多大,是一个实现细节。此外,不包括上面的,是 reference 本身的大小,即“数字”(据说)充当某种地址来告诉盒子的位置。同样是实现细节,但引用可以是 32 位或 64 位数字。
  • 我的 .NET 私​​有实现使用笔和纸,每个字节都用楔形文字书写。它是 ECMA-335 的完美实现,但不为 int32 使用 24 字节。怎么办?我们不应该真正关心我们的数据在内存中的存储位置或方式,或者即使它存在。它可能在月球上,因为它应该有所作为
  • “现在怎么办?我们不应该真正关心我们的数据在内存中的存储位置或方式,或者即使它存在。它可能在月球上,因为它应该会有所作为。” @charlieface 当我们只能使用计算器时,为什么要学习算术?向一个好奇的人发送一个试图更好地了解计算机如何在引擎盖下工作的信息,这是多么可怕的信息。
  • @PeterMoore 并不是说​​我们不应该学习,我们应该学习实现和抽象是如何工作的,但我们也应该知道它是 完全实现定义。这是一个很好的答案,但是first comment above by 中的要点需要更多地强调。否则初学者会认为:这就是它总是的工作原理,而事实并非如此
猜你喜欢
  • 2021-08-22
  • 2020-07-24
  • 2015-11-30
  • 2019-08-12
  • 1970-01-01
  • 1970-01-01
  • 2015-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多