存储在标题和浪费空间中的C#和CLR中的值类型

Storage over heading and wasting space for value types in C# and CLR

我只是一个计算机科学家的二年级学生,正在努力学习更多。我在读一本C书:"简而言之,C",我遇到了这段关于C中存储超标题的内容。

Value-type instances occupy precisely the memory required to store their fields. In
this example, Point takes eight bytes of memory:

struct Point
{
int x; // 4 bytes
int y; // 4 bytes
}

从技术上讲,clr在类型中的位置字段地址是字段大小的倍数(最大为八字节)。因此,下面的内容实际上消耗了16个字节内存(第一个字段后面的七个字节"浪费"):结构A字节B;长L;可以用structLayout重写此行为属性

< /块引用>

我的第一个问题是:为什么只有16字节?为什么不是8或32或其他8的倍数

我的第二个问题是:为什么浪费了


计算机体系结构将最小可寻址空间确定为一个"字"。例如,在32位体系结构中,字是32位或4字节。它是64位体系结构的两倍。处理器操作处理字,而不是字节。

所以,想象一下32位体系结构上的struct MyStruct {byte a; long b;},这需要3个字(12个字节)。在64位体系结构中,这需要16个字节。

1
2
3
4
5
6
7
8
9
10
11
// 8-bit word size (3 1-byte words or 3 bytes) - this is the most compact it can be, but we don't use 8-bit processors.
|1|1|2|3|4|5|6|7|8|
|a|b|b|b|b|b|b|b|b|

// 32-bit word size (3 4-byte words or 12 bytes)
|1234|1234|1234|
|a---|bbbb bbbb|

// 64-bit word size (2 8-byte words or 16-bytes)
|12345678|12345678|
|a-------|bbbbbbbb|


1
struct A { byte b; long l; }

上述struct的内存布局可能如下所示:

1
2
3
4
  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| b |   |   |   |   |   |   |   | l | l | l | l | l | l | l | l |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

byte b放在结构的开头(起始索引0)。它占用一个字节,因此下一个字段的起始索引为1(或更大)。long l将占用8个字节,因此它必须从8的倍数的索引开始。运行时将尝试将字段放在下一个可能的索引处,以便使结构比需要的更大。这就是为什么它将被放置在起始偏移8处。

因此,字节1到7将被EDOCX1的任何字段(5)占用。它们不被A的任何字段使用,而且由于.NET对象不会在内存中相互覆盖,因此不会使用或访问这7个字节。它们是专门为A的一个实例而保留的,但不是为任何事情而保留的,因此它们的空间实际上被浪费了。


在c_中,intSystem.Int32的别名,它是一个32位有符号整数,是4个字节。

当与机器字边界对齐时,处理器访问64位边界的内存通常效率更高,因此编译器可能会将结构的成员与思想中的成员对齐,实际上会在物理结构中留下空白空间,以使访问它们更快。