Sobes.tech
Middle+

Como é estruturada a pilha na linguagem Go?

sobes.tech IA

Resposta da IA

Em Golang, o heap é uma área de memória onde os objetos alocados dinamicamente são colocados. A gestão desta memória é feita automaticamente pelo coletor de lixo.

Aspectos-chave:

  • Alocação dinâmica: Objetos pequenos e de curta duração, onde o compilador não consegue provar que o seu tempo de vida está limitado pelos limites da função ou da pilha, ou que são alocados usando new ou tomando o endereço (&), geralmente são colocados no heap.
  • Coletor de lixo (GC): Go usa um coletor de lixo concorrente, de três cores, Mark-and-Sweep. Funciona em paralelo com a execução do programa, minimizando pausas.
    • Mark (Marcar): O GC percorre os objetos acessíveis a partir dos ponteiros raiz (variáveis locais na pilha, variáveis globais) e os marca como "vivos".
    • Sweep (Varredura): O GC percorre todo o heap acessível e liberta a memória ocupada por objetos que não foram marcados como "vivos".
    • Concorrente: O GC funciona em goroutines separadas, reduzindo atrasos na execução principal.
  • Análise de escape: O compilador Golang realiza uma análise (escape analysis) para determinar se uma variável ou valor aponta para a pilha ou para o heap. Se uma variável ou campo estrutural pode estar acessível após o retorno da goroutine atual, provavelmente será alocada no heap. Caso contrário, pode ser alocada na pilha.
    // Exemplo de análise de escape.
    // Este objeto provavelmente será alocado no heap,
    // pois retorna um ponteiro.
    func createPoint() *Point {
        p := Point{X: 1, Y: 2}
        return &p // Ponteiro "escapa" da função
    }
    
    // Este objeto provavelmente será alocado na pilha,
    // pois não está acessível após a conclusão da função.
    func processValue() {
        val := 10
        println(val)
    }
    
    type Point struct {
        X, Y int
    }
    
  • Divisão em arenas: A memória em Go pode ser dividida em várias arenas, o que ajuda o coletor de lixo a trabalhar de forma mais eficiente, especialmente em sistemas multiprocessados.
  • Uso de mmap: Golang usa a chamada de sistema mmap (Memory Map) para alocar grandes blocos de memória virtual para o heap.
  • Continuidade: Ao contrário de algumas linguagens, Go não garante a continuidade física dos objetos no heap. A memória pode estar fragmentada.
  • Ausência de gestão manual de memória: O desenvolvedor não precisa alocar ou liberar memória explicitamente no heap. O GC faz isso automaticamente.

A pilha e o heap em Golang desempenham papéis diferentes:

Área de memória Propósito Gestão Tempo de vida
Pilha Variáveis locais, parâmetros de funções, endereços de retorno Automático (ao entrar/sair da função) Limitado ao tempo de execução da função
Heap Objetos alocados dinamicamente, aqueles que "escapam" da pilha, estruturas grandes Coletor de lixo (GC) Determinado pela acessibilidade do objeto a partir das raízes