我只是第二年计算机科学家学生,他正在努力学习更多知识。我正在读一本c#书:" c#简而言之"我遇到了关于在c#中标题存储的这一段。
值类型实例恰好占用存储其字段所需的内存。在 在这个例子中,Point需要8个字节的内存:
struct Point { int x; // 4字节 int y; // 4字节 }
从技术上讲,CLR将类型中的字段定位在 地址是字段大小的倍数(最大值) 八个字节)。因此,以下实际上消耗16个字节 内存(第一个字段后面的七个字节“浪费”): struct A {byte b;长l; } 您可以使用StructLayout覆盖此行为 属性
我的第一个问题是:为什么只有16个字节?为什么不是8或32或其他数字是8的倍数
我的第二个问题是:为什么会浪费
答案 0 :(得分:2)
计算机体系结构将最小可寻址空间确定为“单词”。因此,例如,在32位架构上,该字是32位或4字节。它是64位架构的两倍。处理器操作适用于单词,而不是字节。
因此,想象一下32位架构上的struct MyStruct {byte a; long b;}
,这需要3个字(12个字节)。在64位架构上,这需要16个字节。
// 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 :(得分:1)
在C#中,int
是System.Int32
的别名,它是一个32位有符号整数,为4个字节。
当与机器字边界对齐时,处理器通常更有效地访问64位边界的内存,因此编译器可能会将结构的成员与心中的成员对齐,并且实际上在物理空间中留下空白空间结构使其更快地访问它们。
答案 2 :(得分:1)
struct A { byte b; long l; }
上述struct
的内存布局可能如下所示:
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
放在struct的开头(起始索引0)。它占用一个字节,因此下一个字段的起始索引为1(或更大)。 long l
将占用8个字节,因此它必须从8的倍数开始。运行时将尝试将字段放在下一个可能的索引处,以使结构大于它需要是。这就是为什么它将被放置在偏移8的起始位置。
因此,字节1到7将不会被struct A
的任何字段占用。它们不被A
的任何字段使用,并且由于.NET对象不会在内存中相互叠加,因此没有任何东西可以使用或访问这7个字节。它们专门用于A
的实例,但不包含任何内容,因此它们的空间被有效地浪费了。