Автор рассказывает о том, как сборщик мусора работает с базовым типом map. Если кратко, то все зависит от того, сколько места занимает тип, который хранится в map.
* Если тип занимает < 128B, и мы храним его без указателя, то Go не освобождает выделенную память даже после того, как мы явно удаляем все элементы в мапе:
type Client struct {
id uint64
body [40]byte
}
...
m := make(map[int]Client)
for i := range 10000 {
m[i] = Client{id: uint64(i)}
}
runtime.GC()
printAlloc("after create")
for i := range 10000 {
delete(m, i)
}
runtime.GC()
printAlloc("after delete")
Вывод:
initial: heap size = 47 KB
after create: heap size = 1073 KB
after delete: heap size = 1073 KB
* в случае, если размер типа, сохраняемого в map больше, чем 128B, Go автоматически сохраняет его через указатели на куче, и после явного удаления память будет освобождена:
type Client struct {
id uint64
body [1024]byte
}
// the same logic
Вывод:
initial: heap size = 42 KB
after create: heap size = 11581 KB
after delete: heap size = 331 KB
В случае, если вес структуры <128B, то можно явно сохранять в мапе все значения через указатели, и тогда место будет освобождаться.
Иначе, в примере выше порядка 1Mb памяти останется не убранной, что в случае сложной многопоточной логики может значительно увеличить количество потребляемых ресурсов и это стоит держать в голове. Плюс, эти знания могут пригодиться на собесе 🙂