为什么分配的内存比预期的多?

sil*_*ire 5 c# memory benchmarkdotnet

我正在使用 BenchmarkDotNet 及其 MemoryDiagnoser 功能。

考虑以下基准:

[Benchmark]
public void Dummy()
{
   var buffer = new byte[1];
}
Run Code Online (Sandbox Code Playgroud)

我希望它恰好分配 1 个字节。

但是基准测试结果显示总共分配了 32 个字节。怎么来的?我觉得这很有误导性。

| Method |     Mean |     Error |    StdDev |   Median | Ratio | Rank |  Gen 0 | Gen 1 | Gen 2 | Allocated |
|------- |---------:|----------:|----------:|---------:|------:|-----:|-------:|------:|------:|----------:|
|  Dummy | 4.486 ns | 0.1762 ns | 0.5196 ns | 4.650 ns |  1.00 |    1 | 0.0038 |     - |     - |      32 B |

                                                                                      why not 1 byte? ^^^^
Run Code Online (Sandbox Code Playgroud)

Ada*_*nik 5

我是 MemoryDiagnoser 的作者,我在博客中描述了如何读取结果: https: //adamsitnik.com/the-new-Memory-Diagnoser/#how-to-read-the-results

CLR 会进行一些对齐。如果您尝试分配新的 byte[1] 数组,它将分配 byte[8] 数组。

我们需要额外的空间来存放对象头、方法表指针和数组长度。开销是指针大小的 3 倍。对于 32 位,8 + 3x4 = 20;对于 64 位,8 + 3x8 = 32。


Has*_*ngü 0

我怀疑你在 \xe2\x80\x9c/platform:x64\xe2\x80\x9d 上。字节数组将占用“24字节+长度”的空间,因为它的每个元素都是字节的。此外,在 x64 上,所有大小都会四舍五入到最接近的 8 字节。

\n\n

以下是测量尺寸的方法。

\n\n
private void TestMemory(){\n    long before = GC.GetTotalMemory(true);\n    // Allocation code\n    long after = GC.GetTotalMemory(true);\n    double diff = after \xe2\x80\x93 before;\n    Console.WriteLine(\xe2\x80\x9cPer object: \xe2\x80\x9c + diff / size);\n    // Stop the GC from messing up our measurements\n    GC.KeepAlive(array);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

至于你的问题,why?正如评论中提到的,是这种高级语言的实现细节。

\n\n

\xe2\x80\xbb因为内存的对齐\xe2\x86\x90 正如我的回答中提到的

\n\n

\xe2\x80\xbb 数组还包含一些元数据,例如它们的大小,以确保您不会索引到随机内存中。\xe2\x86\x90 这可能与第一颗星有关

\n