Go'da Memory Escape: Stack vs Heap Tahsisini Anlamak

Go'da bir değişken oluşturduğunda, derleyici otomatik olarak onu stack'e mi yoksa heap'e mi koyacağına karar verir. Bu kararı anlama performans ve bellek yönetimi açısından önemli.

Stack hızlı ve otomatik temizlenir, ama boyutu sınırlıdır. Fonksiyon çıktığında stack üzerindeki veriler silinir. Heap ise daha büyük ve uzun ömürlü veriler için kullanılır, ama garbage collector (çöp toplayıcı) tarafından temizlenmeyi bekler.

Go'nun escape analizi adlı bir mekanizması vardır. Derleyici, bir değişkenin fonksiyon dışına "kaçıp" kaçmadığını kontrol eder. Eğer pointer'ı döndürüyorsan ya da global erişim varsa, değişken heap'e taşınır. Aksi takdirde stack'te kalır.

Pratik Örnek:

1package main
2
3import "fmt"
4
5func stackVar() int {
6x:= 42
7return x // x stack'te kalır, sadece değeri döndürülür
8}
9
10func heapVar() *int {
11y:= 100
12return &y // y'nin pointer'ı döndürülüyor y heap'e taşınır
13}
14
15func main() {
16a:= stackVar()
17fmt.Println(a) // Çıktı: 42
18
19b:= heapVar()
20fmt.Println(*b) // Çıktı: 100
21}

Çalıştırdığında her iki fonksiyon da doğru çalışır. Ama heapVar() içinde y escape ediyor, çünkü pointer'ı döndürülüyor. Go bunu algılar ve y'yi heap'e koyar.

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası

Bunu görmek için derleyici analizi çalıştırabilirsin:

1go build -gcflags="-m" main.go

Çıktı şöyle görünür:

1

Bu satırlar hangi değişkenlerin escape ettiğini gösterir. Slice, map ve büyük struct'lar da sık escape eder. Performans kritik kodda bu noktaları takip etmek faydalı olur, çünkü heap tahsisleri stack'ten daha yavaştır ve garbage collection baskısı artırır.

Kısa kural: Eğer fonksiyon içinde oluşturulan bir değişkenin pointer'ını döndürüyorsan ya da global bir yere atıyorsan, escape eder ve heap'e gider.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz