Reputation: 756
Given a map allocation where the initial space is not specified, for example:
foo := make(map[string]int)
The documentation suggests that the memory allocation here is implementation dependent. So (how) can I tell how much memory my implementation is allocating to this map?
Upvotes: 14
Views: 16680
Reputation: 1
I encountered the same requirement, and finally I did it with the help of unsafe, and you can look at MapSize, but it's worth noting that it's not entirely accurate.
Upvotes: 0
Reputation: 10581
If you look at the source of Go's map type, you will see, that a map consists of a header (type hmap
) and an array of buckets (type bmap
). When you create a new map and don't specify the initial space (hint
), only one bucket is created.
A header consists of several fields:
1 * int
,
2 * uint8
,
1 * uint16
,
1 * uint32
,
2 * unsafe.Pointer
,
1 * uintptr
.
Size of the types int
, uintptr
, and unsafe.Pointer
equals the size of a word (8 bytes on 64 bit machines).
A bucket consists of an array of 8 * uint8
.
This gives a total of 40 + 8 = 48 bytes (64 bit architecture)
Upvotes: 17
Reputation: 417542
You may use the Go testing tool to measure size of arbitrary complex data structures. This is detailed in this answer: How to get variable memory size of variable in golang?
To measure the size of a map created by make(map[string]int)
, use the following benchmark function:
var x map[string]int
func BenchmarkEmptyMap(b *testing.B) {
for i := 0; i < b.N; i++ {
x = make(map[string]int)
}
}
Executing with
go test -bench . -benchmem
The result is:
BenchmarkEmptyMap-4 20000000 110 ns/op 48 B/op 1 allocs/op
So the answer is on my 64-bit architecture: 48 bytes.
As hinted, size may depend on architecture. Also size may depend on the initial capacity you may pass to make()
, as you can see in this example:
func BenchmarkEmptyMapCap100(b *testing.B) {
for i := 0; i < b.N; i++ {
x = make(map[string]int, 100)
}
}
Output:
BenchmarkEmptyMapCap100-4 1000000 1783 ns/op 4176 B/op 3 allocs/op
A map of type map[string]int
with an initial capacity of 100 now requires 4176 bytes (on 64-bit arch).
The default initial capacity is around 7 if not specified explicitly.
Upvotes: 15