Dictionary golang maps保留了多少内存?

Dictionary golang maps保留了多少内存?,dictionary,go,heap-memory,Dictionary,Go,Heap Memory,给定未指定初始值的映射分配,例如: foo := make(map[string]int) 这表明这里的内存分配取决于实现。那么(如何)知道我的实现分配给这个映射的内存是多少呢?您可以使用Go测试工具来测量任意复杂数据结构的大小。这在本答复中有详细说明: 要测量由make(map[string]int)创建的映射的大小,请使用以下基准函数: var x map[string]int func BenchmarkEmptyMap(b *testing.B) { for i := 0;

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

foo := make(map[string]int)

这表明这里的内存分配取决于实现。那么(如何)知道我的实现分配给这个映射的内存是多少呢?

您可以使用Go测试工具来测量任意复杂数据结构的大小。这在本答复中有详细说明:

要测量由
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)
    }
}
结果是:

BenchmarkEmptyMap-4     20000000   110 ns/op      48 B/op    1 allocs/op
所以答案就在我的64位体系结构上:48字节

正如所暗示的,规模可能取决于架构。此外,大小可能取决于您可能传递到的初始容量,如本例所示:

func BenchmarkEmptyMapCap100(b *testing.B) {
    for i := 0; i < b.N; i++ {
        x = make(map[string]int, 100)
    }
}
初始容量为100的
map[string]int
类型的映射现在需要4176字节(在64位arch上)

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

如果查看Go的映射类型,您将看到映射由一个标头(type
hmap
)和一个存储桶数组(type
bmap
)组成。创建新映射时,如果不指定初始空间(
hint
),则只创建一个bucket

标题由几个字段组成:

1*
int

2*
uint8

1*
uint16

1*
uint32

2*
不安全。指针

1*
uintptr

类型
int
uintpttr
不安全的大小。指针
等于一个字的大小(64位机器上为8字节)

一个bucket由一个8*
uint8
的数组组成


这将总共提供40+8=48字节(64位体系结构)

如果我分配一个大小为1000的映射,即使映射中的值小于1000,映射的内存使用是否会增加?我想确定一个映射的内存使用情况,或者至少确定一个上限。这是为了评估缓存的内存使用成本。@chmike这个答案为您提供了测试它的工具。你试过了吗?顺便说一句,内存使用和分配可能会由于hashmap内部(Bucket使用和分配)而略有增加。但与整个地图的内存占用相比,这是“微小的”。
func BenchmarkEmptyMapCap100(b *testing.B) {
    for i := 0; i < b.N; i++ {
        x = make(map[string]int, 100)
    }
}
BenchmarkEmptyMapCap100-4   1000000    1783 ns/op   4176 B/op    3 allocs/op