Quando alocações e liberações repetidas quebram o espaço livre em pedaços pequenos, o processo passa a ocupar muito mais memória do que realmente usa.
Por quê Várias threads alocam e liberam, por muito tempo, blocos de memória de tamanhos variados → Efeito O espaço livre fica espalhado em pedaços pequenos que não podem ser devolvidos ao SO, e o uso cresce sem parar, como num vazamento → Na tela Quanto mais tempo ligado, mais lento por swap e falta de memória, até o encerramento forçado
Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento)
O que fazer (Equipe de desenvolvimento)
Pools de memória por tamanho, alocadores resistentes à fragmentação (jemalloc, mimalloc etc.).
No gráfico
Subida lenta · Memória do processo (RSS)
Onde olhar
Subir dois servidores com o mesmo build e, em só um deles, reduzir o número de arenas da glibc com a variável de ambiente MALLOC_ARENA_MAX ou trocar para outro alocador, como o jemalloc; comparar o RSS do pidstat -r durante alguns dias
Confirma se
Com número parecido de jogadores e entidades, só no servidor alterado o RSS para de crescer ou cai bastante
Descarta se
Mesmo com outro alocador o RSS sobe igual: memória que não é liberada (mem-leak)
Como verificar
Ferramentas de infra (sem precisar do código do jogo)
Saiba mais
Como o problema se parece com um vazamento, a análise do heap não mostra nenhum ponto de vazamento. Com o alocador padrão do Linux (glibc), o problema é especialmente forte em servidores com muitas threads, e às vezes só trocar o alocador já reduz muito o uso de memória.
Fontes
mallopt(3) — Linux manual pageLinux man-pages O malloc da glibc cria arenas até um múltiplo do número de CPUs para reduzir a contenção entre threads, e quanto mais arenas, maior o uso de memória (limite com M_ARENA_MAX, também configurável pela variável de ambiente MALLOC_ARENA_MAX)
jemalloc memory allocatorjemalloc Implementação de malloc de uso geral focada em evitar fragmentação e escalar com concorrência