tgoop.com/thank_go/168
Create:
Last Update:
Last Update:
Скукоживание карт в Go
Вижу, не все могут поверить в коварство гошной карты, которая делает кусь не отдает память.
Характерный комментарий:
Если есть сервер на го с сессиями которые реализованы в виде мапы, то даже после отключения клиентов и удаления ключей из нее память не будет освобождаться?🤌
Штош. Давайте разбираться.
Вот наш клиент с идентификатором и телом в 40 байт:
type Client struct {
id uint64
body [40]byte
}
Создаем карту, добавляем 10К клиентов:
printAlloc("initial")
m := make(map[int]Client)
for i := range 10000 {
m[i] = Client{id: uint64(i)}
}
runtime.GC()
printAlloc("after create")
initial: heap size = 109 KB
after create: heap size = 1110 KB
Размер кучи вырос до 1100 KB. Удаляем все записи из карты:
for i := range 10000 {
delete(m, i)
}
runtime.GC()
printAlloc("after delete")
after delete: heap size = 1110 KB
Ни байтика не отдала, зараза!
Попробуем хранить указатели вместо значений:
m := make(map[int]*Client)
for i := range 10000 {
m[i] = &Client{id: uint64(i)}
}
for i := range 10000 {
delete(m, i)
}
after create: heap size = 898 KB
after delete: heap size = 429 KB
Почему часть памяти освободилась?
Здесь в памяти хранятся только указатели на клиентов, а сами значения (48B каждое) хранятся вне карты. Поэтому клиентов GC спокойно спокойно освобождает (ссылок-то на них больше нет), а вот внутренние структуры карты по-прежнему занимают память.
Напоследок предположим, что вместо легкого клиента у нас
type Client struct {
id uint64
body [1024]byte
}
m := make(map[int]Client)
for i := range 10000 {
m[i] = Client{id: uint64(i)}
}
for i := range 10000 {
delete(m, i)
}
after create: heap size = 11683 KB
after delete: heap size = 434 KB
Что за ерунда? Мы же используем значения, а не указатели, почему память освободилась?
Если значения в карте достаточно большие (больше 128B) Go автоматически хранит в карте не сами значения, а указатели на них. Поэтому после GC занятая клиентами память освободилась, и осталась только занятая самой картой память размером 400KB.
песочница (можете поменять версию на dev, и убедиться, что в Go 1.24 ничего не изменилось)
Такие дела.
BY Thank Go!
Share with your friend now:
tgoop.com/thank_go/168