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 main23import "fmt"45func stackVar() int {6x:= 427return x // x stack'te kalır, sadece değeri döndürülür8}910func heapVar() *int {11y:= 10012return &y // y'nin pointer'ı döndürülüyor y heap'e taşınır13}1415func main() {16a:= stackVar()17fmt.Println(a) // Çıktı: 421819b:= heapVar()20fmt.Println(*b) // Çıktı: 10021}Ç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.
Bunu görmek için derleyici analizi çalıştırabilirsin:
1go build -gcflags="-m" main.goÇıktı şöyle görünür:
1Bu 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.
0 yorum