Camada Zero · 13 · Pilha vs Heap & Layout de Processo
Todo processo enxerga a memória do mesmo jeito: código embaixo, e duas regiões que crescem uma em direção à outra. A stack sobe e desce sozinha a cada chamada de função. O heap só cresce quando você aloca, e alguém precisa limpar depois. Empilha chamadas aqui embaixo e veja onde cada coisa vive.
O visualizador é interativo e fica muito melhor numa tela grande. Abra no desktop pra rodar e ver o custo acontecer. A teoria, o código em Go e o Desafio seguem aqui embaixo, dá pra ler tranquilo no celular.
endereços altos ↑endereços baixos ↓
memória livre
data / bss (globais)
text (código)
0Profundidade da stack
0Frames já empilhados
0Alocações no heap
Clica em "chamar função" pra empilhar um frame na stack, ou "alocar no heap" pra reservar memória dinâmica. A "recursão profunda" empilha sem parar até a stack bater no heap.
stack (cresce pra baixo)heap (cresce pra cima)data / text (fixos)
A stack é por goroutine: cada chamada de função empilha um frame com os parâmetros e variáveis locais, e o return descarta o frame inteiro de uma vez. Custo de alocar: mover um ponteiro. O heap é compartilhado por todas as goroutines, guarda o que precisa sobreviver além de uma função, e quem libera é o garbage collector.
—
Stack
Heap
Escopo
por goroutine
compartilhado
Ordem
LIFO (frames)
arbitrária
Alocar
mover ponteiro
bookkeeping
Liberar
no return
via GC
Custo
quase zero
pressão de GC
Stack ou heap? O compilador decide
funcsoma() int {
x := 42// fica na STACK: não escapareturn x
}
funcvaza() *int {
y := 42// ESCAPA pro heap: o ponteiroreturn &y // sobrevive à função (em C, dangling)
}
Ver a decisão (escape analysis)
$ go build -gcflags='-m' main.go
./main.go:8:2: moved to heap: y
./main.go:3:2: x does not escape
🧠 Desafio — Pilha vs Heap
Mexe no visualizador antes de responder. As duas últimas são de reflexão: escreve a sua e só então revela o modelo.