我看到的唯一问题就是你的研究方法。
int[] lengths = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
string[] strs = new string[lengths.Length];
long[] deltaMemory = new long[lengths.Length];
var str0 = new string('A', 1);
var length0 = str0.Length;
long totalMemory0 = GC.GetTotalMemory(true);
long lastTotalMemory = totalMemory0;
for (int i = 0; i < lengths.Length; i++)
{
strs[i] = new string((char)('A' + i), lengths[i]);
long totalMemory = GC.GetTotalMemory(true);
deltaMemory[i] = totalMemory - lastTotalMemory - lengths[i] * 2;
lastTotalMemory = totalMemory;
}
Console.WriteLine("IntPtr.Size: {0}", IntPtr.Size);
for (int i = 0; i < lengths.Length; i++)
{
Console.WriteLine("For size: {0}, extra memory: {1}", strs[i].Length, deltaMemory[i]);
}
你需要记住以下几点:
不要以任何方式分配内存,除了你正在测量的方式
记住第一次调用方法时必须进行JIT编译。我会说这个操作会消耗内存。在使用所有方法之前先预调用一次
.NET中的String
是UTF-16,所以每个字符占用2个字节(lengthts[i] * 2
)
肯定有一些四舍五入,因为内存是按固定块分配的,大小与IntPtr
的大小相关(因此取决于您是否在32位或64位上工作)
结果:
IntPtr.Size: 8
For size: 1, extra memory: 30
For size: 2, extra memory: 28
For size: 3, extra memory: 26
For size: 4, extra memory: 32
For size: 5, extra memory: 30
For size: 6, extra memory: 28
For size: 7, extra memory: 26
For size: 8, extra memory: 32
For size: 9, extra memory: 30
For size: 10, extra memory: 28
For size: 11, extra memory: 26
For size: 12, extra memory: 32
For size: 13, extra memory: 30
For size: 14, extra memory: 28
For size: 15, extra memory: 26
For size: 16, extra memory: 32
For size: 17, extra memory: 30
For size: 18, extra memory: 28
For size: 19, extra memory: 26
For size: 20, extra memory: 32
For size: 21, extra memory: 30
For size: 22, extra memory: 28
For size: 23, extra memory: 26
For size: 24, extra memory: 32
For size: 25, extra memory: 30
For size: 26, extra memory: 28
For size: 27, extra memory: 26
For size: 28, extra memory: 32
For size: 29, extra memory: 30
For size: 30, extra memory: 28
For size: 31, extra memory: 26
For size: 32, extra memory: 32
For size: 64, extra memory: 32
For size: 128, extra memory: 32
For size: 256, extra memory: 32
For size: 512, extra memory: 32
For size: 1024, extra memory: 32
For size: 2048, extra memory: 32
For size: 4096, extra memory: 32
所以每个字符串(64位)都分配了额外的26-32字节。嗯...我看到Skeet甚至写了一篇关于内存分配的博客文章:
http://codeblog.jonskeet.uk/2011/04/05/of-memory-and-strings/
Console.WriteLine(l1.ToString());
也在分配一个字符串。 - Bradley Uffner