Como funciona a alocação(Mallocgc) de memória no golang
Alocador de memória do Go:

No Go, a alocação de memória é feita pelo runtime, não diretamente pelo sistema operacional a cada objeto criado. A ideia central é reduzir contenção, reutilizar blocos pequenos e diminuir chamadas ao OS, o que melhora desempenho e escalabilidade.
Antes de começar vamos falar sobre span em mcache, mcentral, mheap:
Span no mallocgc
No mallocgc, o span é a unidade de trabalho usada pelo runtime para entregar memória para alocações pequenas.
Papel do span
- Um span é um conjunto contíguo de páginas do heap
- Ele é dividido em vários blocos do mesmo tamanho
- Esses blocos são usados para objetos pequenos
Como ele entra no mallocgc
mallocgcrecebe o pedido de alocação- Ele calcula a classe de tamanho
- Se o objeto cabe em uma classe pequena, tenta usar um span disponível no
mcache - Se não houver span no
mcache, busca nomcentral - Se o
mcentralestiver sem span livre, omheapfornece novos spans
Na prática
O span permite que o Go:
- Reutilize memória
- Evite locks globais na maioria das alocações
- Distribua memória de forma eficiente por tamanho
Visão geral da arquitetura
O runtime organiza a memória em alguns níveis:
G = goroutine
P = processor lógico do runtime
M = thread do sistema operacional
mcache = cache local de alocação, ligado ao P
mcentral = estrutura central por classe de tamanho
mheap = heap global do runtime
OS = sistema operacional, origem final da memória
G, P e M
Esses três elementos formam o agendador do Go, mas também impactam a alocação.
G: É a goroutine, a unidade leve de execução.
M: É uma thread real do sistema operacional.
P: É o contexto de execução do runtime. Ele contém recursos necessários para executar goroutines, inclusive acesso ao mcache.
Relação com alocação
Quando uma goroutine (G) precisa alocar memória, ela está rodando em um M com um P.
Esse P fornece acesso rápido ao mcache, evitando disputa global.
mcache:
O mcache é o cache local de alocação.
- Existe um por P. Guarda spans prontos para alocações pequenas
- Evita lock global na maioria dos casos
- É o caminho mais rápido para objetos pequenos
- Papel prático
- Se o programa cria muitos objetos pequenos, o runtime tenta atender diretamente do mcache.
Isso é importante porque a maioria das alocações em aplicações Go é de pequeno porte.
mcentral
O mcentral é o nível intermediário.
- Organiza memória por classe de tamanho
- Cada classe representa um tamanho de objeto pequeno
- Fornece spans para os mcache
- Recebe spans de volta quando necessário
Função:
- Quando o mcache de um P fica sem blocos de uma determinada classe, ele pede mais ao mcentral.
O mcentral reduz a pressão sobre o heap global e organiza melhor a reutilização.
mheap
O mheap é o heap global do runtime.
- Fonte maior de memória gerenciada pelo Go
- Entrega spans para o mcentral
- Gerencia páginas e grandes blocos
- Interage com o coletor de lixo
Função:
- Se o mcentral não consegue atender um pedido, ele busca memória no mheap.
O mheap trabalha em unidades maiores que depois são divididas para uso pelas classes menores.
OS
O OS é a camada final.
Quando o mheap precisa de mais memória, o runtime solicita ao sistema operacional. Isso normalmente ocorre por mecanismos como:
mmap
- Reserva/liberação de páginas
- Ajuste de memória virtual
- Ou seja, o Go tenta não pedir memória ao OS o tempo inteiro.
- Ele mantém estruturas próprias para amortizar esse custo.
Fluxo de alocação
De forma simplificada, a alocação segue esta ordem:
- A goroutine pede memória
- O runtime tenta alocar via mcache
- Se o mcache estiver vazio para aquela classe, busca no mcentral
- Se o mcentral não tiver span disponível, busca no mheap
- Se o mheap precisar crescer, pede memória ao OS
Resumo:
G -> P -> mcache -> mcentral -> mheap -> OS
mallocgc
A função mallocgc é a rotina central de alocação do runtime do Go. É ela que decide como a memória será obtida e preparada.
Papel da mallocgc
Ela cuida de pontos como:
- Tamanho do objeto
- Se o objeto contém ponteiros ou não
- Qual classe de tamanho usar
- Se a alocação pode vir do mcache
- Necessidade de zeroing da memória
- Integração com o garbage collector
O que ele faz na prática:
- Quando o compilador/runtime precisa criar um objeto no heap, a mallocgc entra em ação para:
- Escolher o caminho de alocação
- Reservar a memória adequada
- Marcar metadados importantes para o GC
- Garantir que o objeto esteja em estado válido
- Relação com o GC
A mallocgc é fortemente integrada ao coletor de lixo porque o Go precisa saber:
- Onde há ponteiros
- O que precisa ser rastreado
- Quanto de heap foi consumido
- Quando disparar nova fase de GC
- Como o Go gerencia a memória
0 comentários