【发布时间】:2018-02-26 21:57:03
【问题描述】:
给定一个未指定初始space 的地图分配,例如:
foo := make(map[string]int)
documentation 表明这里的内存分配取决于实现。那么(如何)我可以知道我的实现分配了多少内存给这个映射?
【问题讨论】:
标签: dictionary go heap-memory
给定一个未指定初始space 的地图分配,例如:
foo := make(map[string]int)
documentation 表明这里的内存分配取决于实现。那么(如何)我可以知道我的实现分配了多少内存给这个映射?
【问题讨论】:
标签: dictionary go heap-memory
您可以使用 Go 测试工具来测量任意复杂数据结构的大小。此答案中对此进行了详细说明:How to get variable memory size of variable in 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)
}
}
执行
go test -bench . -benchmem
结果是:
BenchmarkEmptyMap-4 20000000 110 ns/op 48 B/op 1 allocs/op
所以答案在我的 64 位架构上:48 字节。
如前所述,大小可能取决于架构。此外,大小可能取决于您可能传递给 make() 的初始容量,如您在此示例中所见:
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
初始容量为 100 的 map[string]int 类型的映射现在需要 4176 字节(在 64 位架构上)。
如果未明确指定,默认初始容量约为 7。
【讨论】:
如果你看一下 Go 的 map 类型的 source,你会看到,一个 map 由一个 header(type hmap)和一个 bucket 数组(type bmap)组成。当您创建新地图并且不指定初始空间 (hint) 时,只会创建一个存储桶。
一个标头由几个字段组成:
1 * int,
2 * uint8,
1 * uint16,
1 * uint32,
2 * unsafe.Pointer,
1 * uintptr。
int、uintptr 和 unsafe.Pointer 类型的大小等于一个字的大小(在 64 位机器上为 8 个字节)。
一个存储桶由 8 * uint8 的数组组成。
这总共有 40 + 8 = 48 个字节(64 位架构)
【讨论】: