一个字符串在 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";

据我所知,这些块如下:

查看 "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 是对的(怎么可能是错的?)