golang maps 预留多少内存?
Posted
技术标签:
【中文标题】golang maps 预留多少内存?【英文标题】:How much memory do golang maps reserve? 【发布时间】:2018-02-26 21:57:03 【问题描述】:给定一个未指定初始space 的地图分配,例如:
foo := make(map[string]int)
documentation 表明这里的内存分配取决于实现。那么(如何)我可以知道我的实现分配了多少内存给这个映射?
【问题讨论】:
【参考方案1】:您可以使用 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。
【讨论】:
如果我分配一个大小为 1000 的映射,即使映射中的值少于 1000 个,映射的内存使用量会增加吗?我想确定地图的内存使用情况,或者至少确定一个上限。它是评估缓存的内存使用成本。 @chmike 这个答案为您提供了测试它的工具。你有没有尝试过?顺便说一句,是的,由于 hashmap 内部(存储桶的使用和分配),内存使用和分配可能会增加一点。但与整个地图的内存占用相比,这“微不足道”。【参考方案2】:如果你看一下 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 位架构)
【讨论】:
以上是关于golang maps 预留多少内存?的主要内容,如果未能解决你的问题,请参考以下文章