golang地图预留了多少内存?

las*_*ash 5 dictionary heap-memory go

给定未指定初始空间的映射分配,例如:

foo := make(map[string]int)
Run Code Online (Sandbox Code Playgroud)

文件表明,这里的内存分配是依赖于实现.那么(怎么样)我可以告诉我的实现分配给这张地图的内存量是多少?

icz*_*cza 9

您可以使用Go测试工具来测量任意复杂数据结构的大小.这个在这个答案中有详细说明:如何在golang中获取变量的可变内存大小?

要测量由其创建的地图的大小make(map[string]int),请使用以下基准测试功能:

var x map[string]int

func BenchmarkEmptyMap(b *testing.B) {
    for i := 0; i < b.N; i++ {
        x = make(map[string]int)
    }
}
Run Code Online (Sandbox Code Playgroud)

执行

go test -bench . -benchmem
Run Code Online (Sandbox Code Playgroud)

结果是:

BenchmarkEmptyMap-4     20000000   110 ns/op      48 B/op    1 allocs/op
Run Code Online (Sandbox Code Playgroud)

所以答案是我的64位架构:48个字节.

如所暗示的,尺寸可能取决于架构.另外,大小可能取决于您可能传递给的初始容量make(),如您在此示例中所示:

func BenchmarkEmptyMapCap100(b *testing.B) {
    for i := 0; i < b.N; i++ {
        x = make(map[string]int, 100)
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

BenchmarkEmptyMapCap100-4   1000000    1783 ns/op   4176 B/op    3 allocs/op
Run Code Online (Sandbox Code Playgroud)

map[string]int初始容量为100 的类型映射现在需要4176个字节(在64位拱门上).

如果未明确指定,则默认初始容量约为7.


dev*_*max 6

如果你看一下Go的地图类型的来源,你会看到一个地图由一个标题(类型hmap)和一个桶数组(类型bmap)组成.创建新映射但未指定初始空间(hint)时,仅创建一个存储桶.

标题包含几个字段:

1*int,
2*uint8,
1*uint16,
1*uint32,
2*unsafe.Pointer,
1*uintptr.

类型的大小int,uintptrunsafe.Pointer等于一个字(64台机器8个字节)的大小.

一个桶由8*的数组组成uint8.

这总共提供40 + 8 = 48字节(64位架构)