De Go-compiler past het mechanisme van escape analysis toe: alle waarden worden standaard op de stack geplaatst, maar als een variabele "de scope verlaat" (bijvoorbeeld wanneer er een pointer naar een lokale variabele wordt geretourneerd), wordt deze automatisch op de heap geplaatst.
Dit is belangrijk voor de prestaties:
De compiler probeert te bepalen of een object op de stack kan worden geplaatst, maar als het impliciet "overleeft" buiten de functiegrenzen, wordt het op de heap geplaatst.
Voorbeeld met ontsnapping:
func NewPoint() *int { a := 42 return &a // ontsnap naar heap! }
Voorbeeld zonder ontsnapping:
func Sum(a, b int) int { c := a + b return c // op de stack }
Gebruik go build -gcflags='-m' voor diagnostiek in de compiler, om details te zien:
go build -gcflags='-m' main.go
"Zal een object naar de heap gaan als we alleen zijn waarde teruggeven — geen pointer?"
Vaak wordt aangenomen dat alle geretourneerde waarden "naar de heap gaan". In werkelijkheid, als er een waarde (geen pointer) wordt geretourneerd, kan de variabele op de stack blijven.
Voorbeeld:
func F() int { x := 10 return x // stackallocatie, gaat niet naar heap }
Verhaal
Bij het massaal creëren van structuren via een fabrieksfunctie die pointers naar lokale variabelen retourneert, steeg het geheugengebruik en de belasting van de GC aanzienlijk. Het bleek dat alle objecten naar de heap gingen vanwege de terugkeer van een pointer naar een lokale variabele, hoewel dit vermeden had kunnen worden door de waarde terug te geven.
Verhaal
In een microservice leidde het doorgeven van pointers tussen goroutines en het retourneren ervan vanuit verschillende functies ertoe dat er veel objecten van de stack naar de heap "weglekten", wat de prestaties vertraagde en leidde tot frequente pauzes van de GC.
Verhaal
Een ontwikkelaar wikkelde per ongeluk een statische array in een slice binnen een functie, retourneerde een pointer naar de slice — en begon bij een belastingstest geheugensLeaks te vangen. Diagnostiek toonde aan dat de variabele niet "over de grenzen van de functie heen was", maar Go besloot ten onrechte om deze in de heap te plaatsen vanwege het indirecte gebruik.