Go'da Garbage Collection
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 23 / 107.
C veya C++ gibi dillerin aksine Go, bellek yönetimini çöp toplama (garbage collection - GC) aracılığıyla otomatik olarak gerçekleştirir. İşiniz bittiğinde belleği manuel olarak boşaltmanıza gerek yoktur. Go çalışma zamanı (runtime), hangi belleğin hala kullanımda olduğunu takip eder ve geri kalanını geri kazanır.
new(), make() kullanarak veya değişkenler oluşturarak bellek tahsis ettiğinizde, Go'nun çöp toplayıcısı (garbage collector) bu tahsisleri izler. Bir değere programınızın herhangi bir bölümünden artık erişilemediğinde, GC bu belleği otomatik olarak serbest bırakır.
func createPerson() *Person {
p := &Person{Name: "Alice", Age: 30}
return p // p heap'e çıkar, GC onu yönetecektir
}
func main() {
person := createPerson()
fmt.Println(person.Name)
// person artık kullanılmadığında, GC belleği geri kazanır
}Bu örnekte, Person yapısı fonksiyondan döndürüldüğü için heap üzerinde tahsis edilir. Go derleyicisi, bir değişkenin stack'te mi kalabileceğini yoksa heap'e mi taşınması gerektiğini belirlemek için kaçış analizi (escape analysis) gerçekleştirir. Çöp toplayıcı (garbage collector) yalnızca heap belleğini yönetir.
Bu otomatik bellek yönetimi, unutulan bellek boşaltma işlemlerinden kaynaklanan bellek sızıntıları hakkında endişelenmeden uygulamanızı oluşturmaya odaklanabileceğiniz anlamına gelir. Ancak, GC'nin var olduğunu anlamak, performansın önemli olduğu durumlarda gereksiz tahsisleri en aza indirerek daha verimli kod yazmanıza yardımcı olur.
Görev
KolayGo'nin çöp toplayıcısının (garbage collector) yığına (heap) sızan nesneler için belleği nasıl yönettiğini gösteren bir oturum yöneticisi oluşturalım. Dinamik olarak tahsis edilen ve fonksiyonlardan döndürülen oturumlar oluşturacaksınız, böylece yaşam döngülerini GC'nin yönetmesine izin vereceksiniz.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
session.go:ID(string),Username(string) veData(string dilimi - slice) alanlarına sahip birSessionyapısı (struct) tanımlayın. Bir ID ve kullanıcı adı alan, yığında yeni bir Session tahsis eden (bir işaretçi - pointer döndürerek) ve Data dilimini boş olarak başlatan birNewSessionfonksiyonu oluşturun. Ayrıca, oturumun Data dilimine bir string ekleyen işaretçi alıcılı (pointer receiver) birAddDatametodu ve oturum ayrıntılarını gösteren biçimlendirilmiş bir string döndüren birSummarymetodu ekleyin.main.go: Girişten oturum bilgilerini okuyun, yapıcı (constructor) fonksiyonunuzu kullanarak bir oturum oluşturun, ona bazı veri girişleri ekleyin ve oturum özetini görüntüleyin. Oturum bir fonksiyon içinde oluşturulup bir işaretçi olarak döndürüldüğü için, çöp toplayıcının onu yöneteceği yığına (heap) sızar.
Aşağıdaki girişler sağlanacaktır:
- Satır 1: Session ID
- Satır 2: Username
- Satır 3: Eklenecek ilk veri girişi
- Satır 4: Eklenecek ikinci veri girişi
Summary metodunuz şu formatta bir string döndürmelidir:
Session [ID] for user [Username]
Data entries: [count]
- [entry1]
- [entry2]Örneğin, sess-001, alice, login ve view_dashboard verildiğinde, çıktınız şöyle olmalıdır:
Session sess-001 for user alice
Data entries: 2
- login
- view_dashboardBuradaki temel nokta, NewSession fonksiyonunuzun bir Session oluşturması ve ona bir işaretçi döndürmesidir. Bu, Session'ın yığında (stack) kalmak yerine yığına (heap) "sızmasına" (escape) neden olur ve ona yönelik hiçbir referans kalmadığında çöp toplama için uygun hale gelir. Kodunuzun bu belleği manuel olarak serbest bırakması gerekmez; Go bunu otomatik olarak halleder.
Kopya kağıdı
Go, otomatik bellek yönetimi için çöp toplama (garbage collection - GC) kullanır. Belleği manuel olarak boşaltmanıza gerek yoktur.
Çöp toplayıcı, bellek tahsislerini izler ve programınız tarafından artık erişilemeyen belleği geri kazanır.
func createPerson() *Person {
p := &Person{Name: "Alice", Age: 30}
return p // p yığına (heap) kaçar, GC onu yönetecektir
}
func main() {
person := createPerson()
fmt.Println(person.Name)
// person artık kullanılmadığında, GC belleği geri kazanır
}Go derleyicisi, bir değişkenin yığında (stack) mı kalacağını yoksa öbeğe (heap) mi taşınacağını belirlemek için kaçış analizi (escape analysis) gerçekleştirir. Öbeğe kaçan değişkenler (döndürülen işaretçiler gibi) çöp toplayıcı tarafından yönetilir.
GC yalnızca öbek (heap) belleğini yönetir, yığın (stack) belleğini yönetmez. Yığın belleği, bir fonksiyon döndüğünde otomatik olarak boşaltılır.
Kendin dene
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Oturum kimliğini oku
sessionID, _ := reader.ReadString('\n')
sessionID = sessionID[:len(sessionID)-1]
// Kullanıcı adını oku
username, _ := reader.ReadString('\n')
username = username[:len(username)-1]
// İlk veri girişini oku
data1, _ := reader.ReadString('\n')
data1 = data1[:len(data1)-1]
// İkinci veri girişini oku
data2, _ := reader.ReadString('\n')
data2 = data2[:len(data2)-1]
// TODO: NewSession fonksiyonunu kullanarak yeni bir oturum oluşturun
// Bir pointer döndürdüğümüz için oturum heap'e çıkacaktır
// TODO: AddData metodunu kullanarak veri girişlerini oturuma ekleyin
// TODO: Summary metodunu kullanarak oturum özetini yazdırın
fmt.Println("")
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Go OOP Temelleri
Harici DosyalarGo Çalışma Alanı ve ModüllerPaketler ve İçe AktarmalarDışa Aktarılan ve Aktarılmayan İsimlerGo'da OOP'ye GirişSınıf Olarak Struct'larStruct'larda Metot TanımlamaPointer ve Değer AlıcılarStruct BaşlatmaYapıcı FonksiyonlarÖzet - Basit Hesap Makinesi4Arayüzler
Arayüzlere GirişÖrtük UygulamaSözleşme Olarak ArayüzBoş Arayüz (any)Tür OnaylamaTür SeçimiArayüz BileşimiStringer ve Error ArayüzleriÖzet - Şekil Hesaplayıcı7Kapsülleme
Dışa Aktarılan ve Aktarılmayan AlanlarPaket Seviyesinde KapsüllemeGetter ve Setter MetotlarıGo'da Bilgi GizlemeÖzet - Öğrenci Kayıtları10Generics (Go 1.18+)
Generics'e GirişTür ParametreleriTür KısıtlamalarıGeneric Struct'larGeneric Metotlar İçin Geçici ÇözümÖzet - Generic Koleksiyon13Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıAbstract Factory KalıbıObserver KalıbıStrategy Kalıbı2Türler ve Struct'lar: Derinlemesine İnceleme
Temel ve Bileşik TürlerÖzel Tür TanımlamalarıStruct EtiketleriAnonim Struct'larİç İçe Geçmiş Struct'larSıfır Değerler ve VarsayılanlarÖzet - Rehber5Kalıtım Yerine Kompozisyon
Go'da Neden Kalıtım YokStruct Gömme TemelleriMetot YükseltmeBirden Fazla Struct GömmeGömme vs AgregasyonGömülü Metotları GölgelemeÖzet - Çalışan Hiyerarşisi8Hata Yönetimi ve OOP
error ArayüzüÖzel Hata TürleriHata Sarmalama (fmt.Errorf)Sentinel Hatalarerrors.Is() ve errors.As()Panic, Defer ve RecoverÖzet - Dosya Ayrıştırıcı3İşaretçiler ve Bellek
Go'da İşaretçi TemelleriStruct İşaretçileriDeğer ile Geçme ve Referans ile Geçmenew() FonksiyonuGo'da Garbage CollectionÖzet - Linked List Oluşturucu6Go'da Polimorfizm
Interface'ler ile PolimorfizmGo'da Duck TypingInterface Karşılama KurallarıPolimorfik KoleksiyonlarDependency InjectionÖzet - Payment Processor9Eşzamanlılık ve OOP
Goroutine TemelleriKanallar ve İletişimTamponlu ve Tamponsuz KanallarSelect İfadesisync.Mutex ve sync.RWMutexsync.WaitGroupThread-Safe Struct TasarımıÖzet - Worker Pool