一个字符串在 x64 中占用多少字节?
How many bytes does a string take up in x64?
出于学习的目的,我试图了解 C# 字符串在内存中的内部存储方式。
根据此 blog post,C# 字符串大小为(x64 with .NET Framework 4.0):
26 + 2 * length
具有单个字符的字符串将占用 (26 + 2 * 1) / 8 * 8 = 32 bytes
。
这确实和我测量的差不多。
令我困惑的是那 26 字节的开销是什么。
我有 运行 以下代码并检查了内存:
string abc = "abcdeg";
string aaa = "x";
string ccc = "zzzzz";
据我所知,这些块如下:
- 绿色:同步块(8 字节)
- 青色:类型信息(8 字节)
- 黄色:长度(4 字节)
- 粉红色:实际字符:每个字符 2 个字节 + 2 个字节用于 NULL 终止符。
查看 "x" 字符串。确实是32字节(按计算)。
无论如何,如果用零填充,它看起来像是字符串的结尾。
"x" 字符串可以在 NULL 终止符的两个字节之后结束,并且仍然是内存对齐的(因此是 24 个字节)。
为什么我们需要额外的 8 个字节?
我用其他(更大的)字符串大小试验了类似的结果。
看起来总是多了8个字节。
正如 Hans Passant 所建议的,在字符串对象的末尾添加了一个额外的字段,它是 4 个字节(在 x64 中,它可能需要额外的 4 个字节,用于填充)。
所以最后我们有:
= 8 (sync) + 8 (type) + 4 (length) + 4(extra field) + 2 (null terminator) + 2 * length
= 26 + 2 * length
所以 Jon Skeet 的博客 post 是对的(怎么可能是错的?)
出于学习的目的,我试图了解 C# 字符串在内存中的内部存储方式。
根据此 blog post,C# 字符串大小为(x64 with .NET Framework 4.0):
26 + 2 * length
具有单个字符的字符串将占用 (26 + 2 * 1) / 8 * 8 = 32 bytes
。
这确实和我测量的差不多。
令我困惑的是那 26 字节的开销是什么。
我有 运行 以下代码并检查了内存:
string abc = "abcdeg";
string aaa = "x";
string ccc = "zzzzz";
据我所知,这些块如下:
- 绿色:同步块(8 字节)
- 青色:类型信息(8 字节)
- 黄色:长度(4 字节)
- 粉红色:实际字符:每个字符 2 个字节 + 2 个字节用于 NULL 终止符。
查看 "x" 字符串。确实是32字节(按计算)。
无论如何,如果用零填充,它看起来像是字符串的结尾。 "x" 字符串可以在 NULL 终止符的两个字节之后结束,并且仍然是内存对齐的(因此是 24 个字节)。 为什么我们需要额外的 8 个字节?
我用其他(更大的)字符串大小试验了类似的结果。 看起来总是多了8个字节。
正如 Hans Passant 所建议的,在字符串对象的末尾添加了一个额外的字段,它是 4 个字节(在 x64 中,它可能需要额外的 4 个字节,用于填充)。
所以最后我们有:
= 8 (sync) + 8 (type) + 4 (length) + 4(extra field) + 2 (null terminator) + 2 * length
= 26 + 2 * length
所以 Jon Skeet 的博客 post 是对的(怎么可能是错的?)