[{"data":1,"prerenderedAt":1146},["ShallowReactive",2],{"post-\u002Ftr\u002Fgarbage-collection-ve-golang":3},{"page":4,"translation":983,"nav":998,"related":1127,"random":1137},{"id":5,"title":6,"body":7,"categories":981,"category":983,"date":984,"description":985,"draft":986,"extension":987,"image":988,"kind":983,"lang":68,"meta":989,"navigation":191,"path":990,"readingTime":213,"seo":991,"slug":992,"stem":993,"tags":994,"translationKey":992,"type":982,"updated":996,"__hash__":997},"postsTr\u002Ftr\u002Fgarbage-collection-ve-golang.md","Garbage Collection ve Go (Golang)",{"type":8,"value":9,"toc":972},"minimark",[10,47,50,53,56,61,137,139,158,160,165,168,448,455,461,483,486,492,498,500,504,522,705,708,713,722,725,727,731,737,927,932,935,939,945,948,952,955,960,968],[11,12,13,21],"blockquote",{},[14,15,16,17],"p",{},"💡 ",[18,19,20],"strong",{},"Özet (TL;DR):",[22,23,24,31,41],"ul",{},[25,26,27,30],"li",{},[18,28,29],{},"Garbage Collection (GC) Nedir?:"," Programın artık ihtiyaç duymadığı heap belleğindeki nesneleri otomatik olarak tespit edip temizleyen arka plan mekanizmasıdır.",[25,32,33,36,37,40],{},[18,34,35],{},"Go GC Stratejisi:"," Go, bellek tahsisatı (allocation) ve GOGC eşik değerlerini izleyerek çöp toplamayı otomatik başlatır. Yerel değişkenlerin ömrünü belirlemek için ",[18,38,39],{},"Kaçış Analizi (Escape Analysis)"," kullanır.",[25,42,43,46],{},[18,44,45],{},"Kritik Fark:"," Değişkenlerin kapsamını (scope) dar tutmak, nesnelerin ömrünü netleştirir ve GC'nin belleği hızlıca geri kazanmasını sağlar. Global değişkenler ise her zaman GC kökü (root) olarak kaldığından bellek yönetimini zorlaştırır.",[14,48,49],{},"Türkçe karşılığı \"Çöp Toplama\" olan Garbage Collection, özetle artık kullanılmayan hafıza alanının boşaltılması anlamına gelir. Programlamada çöpleri kimin toplayacağı daha çok kullandığınız programlama diliyle ilişkilidir; fakat artık çoğu modern dilde hafıza yönetimiyle doğrudan uğraşmadan, bu süreci dilin çalışma zamanına (runtime) bırakabiliyoruz. Programlama dilinin bu desteği sağlaması daha az kod yazmamızı sağlarken olası hataların da önüne geçiyor.",[14,51,52],{},"Garbage Collection sürecinin nasıl çalıştığını anlarsak, bu sürecin daha verimli ve daha doğru işlemesini sağlayabiliriz. Bu yazıda Go Garbage Collection sürecinin nasıl işlediğini inceleyerek daha verimli bellek yönetimi için ipuçları elde etmiş olacağız.",[54,55],"hr",{},[57,58,60],"h3",{"id":59},"go-bellek-yönetimi-stack-vs-heap","Go Bellek Yönetimi: Stack vs. Heap",[62,63,64,81],"table",{},[65,66,67],"thead",{},[68,69,70,75,78],"tr",{},[71,72,74],"th",{"align":73},"left","Özellik",[71,76,77],{"align":73},"Stack (Yığın)",[71,79,80],{"align":73},"Heap (Yığın Kümesi)",[82,83,84,98,111,124],"tbody",{},[68,85,86,92,95],{},[87,88,89],"td",{"align":73},[18,90,91],{},"Yönetim",[87,93,94],{"align":73},"CPU tarafından otomatik yönetilir (LIFO mantığı)",[87,96,97],{"align":73},"Garbage Collector (GC) tarafından yönetilir",[68,99,100,105,108],{},[87,101,102],{"align":73},[18,103,104],{},"Hız",[87,106,107],{"align":73},"Son derece hızlıdır",[87,109,110],{"align":73},"Stack'e göre daha yavaş çalışır (GC tarama yükü)",[68,112,113,118,121],{},[87,114,115],{"align":73},[18,116,117],{},"Değişken Ömrü",[87,119,120],{"align":73},"Fonksiyon sonlandığında otomatik temizlenir",[87,122,123],{"align":73},"Kökten (root) hiçbir referans kalmayana kadar yaşar",[68,125,126,131,134],{},[87,127,128],{"align":73},[18,129,130],{},"Kullanım",[87,132,133],{"align":73},"Kısa ömürlü, boyutu derleme anında bilinen değişkenler",[87,135,136],{"align":73},"Dinamik boyutlu, fonksiyon dışına kaçan (escape) nesneler",[54,138],{},[11,140,141,155],{},[14,142,16,143,146,147,150,151,154],{},[18,144,145],{},"Bellek Alanları Üzerine Kısa Bir Not:","\nÇalışan bir program nesneleri iki farklı hafıza bölümünde depolar; bunlardan biri ",[18,148,149],{},"heap",", diğeri ise ",[18,152,153],{},"stack"," olarak adlandırılır. Garbage Collection'ın işi stack'le değil, heap iledir. Stack, son giren ilk çıkar (LIFO) mantığına dayanan ve fonksiyon değerlerini saklayan bir veri yapısıdır. Bir fonksiyonun içinden başka bir fonksiyonu çağırmak, stack'te o fonksiyonun değerlerini saklayan yeni bir çerçeve (frame) açar.",[14,156,157],{},"Hata veren bir programı veya betiği debug yaptıysanız stack yapısına aşina olmalısınız. Birçok programlama dilinin derleyicisi debug amaçlı bir call stack ağacı görüntüler. Öte yandan heap, fonksiyonların dışında referans verilen veya dinamik olarak oluşturulan nesneleri saklar. Programın başında tanımlanan statik sabitler veya Go struct'ları gibi daha karmaşık nesneler buna örnektir. Heap alanına kaydedilmesi gereken bir nesne tanımladığınızda gereken hafıza ayrılır ve bir pointer geri döndürülür. Heap temizlenmezse program çalıştıkça bellek tüketimi büyümeye devam eder.",[54,159],{},[161,162,164],"h2",{"id":163},"bellek-durumunu-i̇zleyen-örnek-kod","Bellek Durumunu İzleyen Örnek Kod",[14,166,167],{},"Hafızayı biraz dolduracak ve bize bellek durumunu gösterecek kısa bir Go kodu yazalım:",[169,170,175],"pre",{"className":171,"code":172,"language":173,"meta":174,"style":174},"language-go shiki shiki-themes github-light github-dark","package main\n\nimport (\n    \"fmt\"\n    \"runtime\"\n    \"time\"\n)\n\nfunc printStats(memory runtime.MemStats) {\n    runtime.ReadMemStats(&memory)\n    fmt.Println(\"Memory Allocation       :\", memory.Alloc)\n    fmt.Println(\"Memory Total Allocation :\", memory.TotalAlloc)\n    fmt.Println(\"Memory Heap Allocation  :\", memory.HeapAlloc)\n    fmt.Println(\"Memory NumGC            :\", memory.NumGC)\n    fmt.Println(\"**********************************\")\n    fmt.Print(\"\\n\")\n}\n\nfunc main() {\n    fmt.Print(\"\\n\")\n    var memory runtime.MemStats\n    fmt.Println(\"************* START **************\")\n    printStats(memory)\n\n    var s []byte\n\n    for i := 0; i \u003C 10; i++ {\n        s = make([]byte, 52428800)\n        if s == nil {\n            fmt.Println(\"Operation failed!\")\n        }\n    }\n\n    fmt.Println(\"********* ALLOCATE 50M ***********\")\n    printStats(memory)\n\n    for i := 0; i \u003C 10; i++ {\n        s = make([]byte, 104587600)\n        if s == nil {\n            fmt.Println(\"Operation failed!\")\n        }\n    }\n    time.Sleep(3 * time.Second)\n    fmt.Println(\"********* ALLOCATE 100 M *********\")\n    printStats(memory)\n    fmt.Printf(\"%T\\n\", s)\n}\n","go","",[176,177,178,186,193,199,205,211,217,223,228,234,240,246,252,258,264,270,276,282,287,293,298,304,310,316,321,327,332,338,344,350,356,362,368,373,379,384,389,394,400,405,410,415,420,426,432,437,443],"code",{"__ignoreMap":174},[179,180,183],"span",{"class":181,"line":182},"line",1,[179,184,185],{},"package main\n",[179,187,189],{"class":181,"line":188},2,[179,190,192],{"emptyLinePlaceholder":191},true,"\n",[179,194,196],{"class":181,"line":195},3,[179,197,198],{},"import (\n",[179,200,202],{"class":181,"line":201},4,[179,203,204],{},"    \"fmt\"\n",[179,206,208],{"class":181,"line":207},5,[179,209,210],{},"    \"runtime\"\n",[179,212,214],{"class":181,"line":213},6,[179,215,216],{},"    \"time\"\n",[179,218,220],{"class":181,"line":219},7,[179,221,222],{},")\n",[179,224,226],{"class":181,"line":225},8,[179,227,192],{"emptyLinePlaceholder":191},[179,229,231],{"class":181,"line":230},9,[179,232,233],{},"func printStats(memory runtime.MemStats) {\n",[179,235,237],{"class":181,"line":236},10,[179,238,239],{},"    runtime.ReadMemStats(&memory)\n",[179,241,243],{"class":181,"line":242},11,[179,244,245],{},"    fmt.Println(\"Memory Allocation       :\", memory.Alloc)\n",[179,247,249],{"class":181,"line":248},12,[179,250,251],{},"    fmt.Println(\"Memory Total Allocation :\", memory.TotalAlloc)\n",[179,253,255],{"class":181,"line":254},13,[179,256,257],{},"    fmt.Println(\"Memory Heap Allocation  :\", memory.HeapAlloc)\n",[179,259,261],{"class":181,"line":260},14,[179,262,263],{},"    fmt.Println(\"Memory NumGC            :\", memory.NumGC)\n",[179,265,267],{"class":181,"line":266},15,[179,268,269],{},"    fmt.Println(\"**********************************\")\n",[179,271,273],{"class":181,"line":272},16,[179,274,275],{},"    fmt.Print(\"\\n\")\n",[179,277,279],{"class":181,"line":278},17,[179,280,281],{},"}\n",[179,283,285],{"class":181,"line":284},18,[179,286,192],{"emptyLinePlaceholder":191},[179,288,290],{"class":181,"line":289},19,[179,291,292],{},"func main() {\n",[179,294,296],{"class":181,"line":295},20,[179,297,275],{},[179,299,301],{"class":181,"line":300},21,[179,302,303],{},"    var memory runtime.MemStats\n",[179,305,307],{"class":181,"line":306},22,[179,308,309],{},"    fmt.Println(\"************* START **************\")\n",[179,311,313],{"class":181,"line":312},23,[179,314,315],{},"    printStats(memory)\n",[179,317,319],{"class":181,"line":318},24,[179,320,192],{"emptyLinePlaceholder":191},[179,322,324],{"class":181,"line":323},25,[179,325,326],{},"    var s []byte\n",[179,328,330],{"class":181,"line":329},26,[179,331,192],{"emptyLinePlaceholder":191},[179,333,335],{"class":181,"line":334},27,[179,336,337],{},"    for i := 0; i \u003C 10; i++ {\n",[179,339,341],{"class":181,"line":340},28,[179,342,343],{},"        s = make([]byte, 52428800)\n",[179,345,347],{"class":181,"line":346},29,[179,348,349],{},"        if s == nil {\n",[179,351,353],{"class":181,"line":352},30,[179,354,355],{},"            fmt.Println(\"Operation failed!\")\n",[179,357,359],{"class":181,"line":358},31,[179,360,361],{},"        }\n",[179,363,365],{"class":181,"line":364},32,[179,366,367],{},"    }\n",[179,369,371],{"class":181,"line":370},33,[179,372,192],{"emptyLinePlaceholder":191},[179,374,376],{"class":181,"line":375},34,[179,377,378],{},"    fmt.Println(\"********* ALLOCATE 50M ***********\")\n",[179,380,382],{"class":181,"line":381},35,[179,383,315],{},[179,385,387],{"class":181,"line":386},36,[179,388,192],{"emptyLinePlaceholder":191},[179,390,392],{"class":181,"line":391},37,[179,393,337],{},[179,395,397],{"class":181,"line":396},38,[179,398,399],{},"        s = make([]byte, 104587600)\n",[179,401,403],{"class":181,"line":402},39,[179,404,349],{},[179,406,408],{"class":181,"line":407},40,[179,409,355],{},[179,411,413],{"class":181,"line":412},41,[179,414,361],{},[179,416,418],{"class":181,"line":417},42,[179,419,367],{},[179,421,423],{"class":181,"line":422},43,[179,424,425],{},"    time.Sleep(3 * time.Second)\n",[179,427,429],{"class":181,"line":428},44,[179,430,431],{},"    fmt.Println(\"********* ALLOCATE 100 M *********\")\n",[179,433,435],{"class":181,"line":434},45,[179,436,315],{},[179,438,440],{"class":181,"line":439},46,[179,441,442],{},"    fmt.Printf(\"%T\\n\", s)\n",[179,444,446],{"class":181,"line":445},47,[179,447,281],{},[14,449,450,451,454],{},"Bu kodda hafızanın durumunu görüntülemek için Go standart kütüphanesinde yer alan ",[176,452,453],{},"runtime"," paketini kullandık.",[14,456,457,460],{},[176,458,459],{},"runtime.ReadMemStats"," metodunu kullanarak bellek durumuyla ilgili istatistikleri elde edip bunları ekrana basan bir fonksiyonumuz var. Main fonksiyonumuz içerisinde sırasıyla şunları yapıyoruz:",[22,462,463,466,480],{},[25,464,465],{},"Önce mevcut hafıza durumunu ekrana basıyoruz.",[25,467,468,469,472,473,476,477,479],{},"Ardından bir ",[176,470,471],{},"for"," döngüsü içerisinde ",[176,474,475],{},"s"," isimli bir değişkene 10 defa 50 MB değerinde bir byte dilimi (slice) atıyoruz. Aslında her seferinde ",[176,478,475],{}," değişkeninin üzerine yazmış oluyoruz.",[25,481,482],{},"Ardından aynı döngüyü 100 MB ile tekrarlıyoruz.",[14,484,485],{},"Programı çalıştırdığımızda şöyle bir çıktı elde ederiz:",[14,487,488],{},[489,490],"img",{"alt":174,"src":491},"\u002Fimages\u002Fgarbage-collection-ve-golang\u002Fimage-1.avif",[14,493,494,495,497],{},"Birinci çıktıda toplam ayrılmış bellek 154.472 byte iken, ikinci çıktıda 50 MB'ın üzerinde olduğunu görüyoruz. Anlık ayrılan hafıza 50 MB civarında doluyken, atama işlemi 10 defa yapıldığı için toplam 500 MB bellek ayrılmıştır. Her yeni değer atama işleminde hafızada yeni bir alan ayrılıp ",[176,496,475],{}," değişkeni bu alan (pointer) ile ilişkilendirilir. Bir önceki hafıza pointer'ının ilişkili olduğu hiçbir nesne kalmadığından Garbage Collector o alanı temizler. Sonuç olarak GC çalıştı, gereksiz hafıza alanlarını boşalttı ve sadece gereken hafıza alanı saklanmaya devam etti.",[54,499],{},[161,501,503],{"id":502},"değişken-kapsamını-scope-daraltmak","Değişken Kapsamını (Scope) Daraltmak",[14,505,506,507,510,511,514,515,518,519,521],{},"Şimdi kodun sadece ",[176,508,509],{},"main"," fonksiyonu içerisinde ufak bir değişiklik yapalım. Fonksiyonun başındaki ",[176,512,513],{},"var s []byte"," tanımını kaldıralım ve döngünün içini ",[176,516,517],{},"s :="," haline getirelim. Böylece değişkeni ",[176,520,471],{}," döngüsünün içinde tanımlamış olacağız.",[169,523,525],{"className":171,"code":524,"language":173,"meta":174,"style":174},"package main\n\nimport (\n    \"fmt\"\n    \"runtime\"\n    \"time\"\n)\n\nfunc printStats(memory runtime.MemStats) {\n    runtime.ReadMemStats(&memory)\n    fmt.Println(\"Memory Allocation       :\", memory.Alloc)\n    fmt.Println(\"Memory Total Allocation :\", memory.TotalAlloc)\n    fmt.Println(\"Memory Heap Allocation  :\", memory.HeapAlloc)\n    fmt.Println(\"Memory NumGC            :\", memory.NumGC)\n    fmt.Println(\"**********************************\")\n    fmt.Print(\"\\n\")\n}\n\nfunc main() {\n    fmt.Print(\"\\n\")\n    var memory runtime.MemStats\n    fmt.Println(\"************* START **************\")\n    printStats(memory)\n\n    for i := 0; i \u003C 10; i++ {\n        s := make([]byte, 52428800)\n        if s == nil {\n            fmt.Println(\"Operation failed!\")\n        }\n    }\n\n    fmt.Println(\"********* ALLOCATE 50M ***********\")\n    printStats(memory)\n\n    for i := 0; i \u003C 10; i++ {\n        s := make([]byte, 104587600)\n        if s == nil {\n            fmt.Println(\"Operation failed!\")\n        }\n    }\n    time.Sleep(3 * time.Second)\n    fmt.Println(\"********* ALLOCATE 100 M *********\")\n    printStats(memory)\n}\n",[176,526,527,531,535,539,543,547,551,555,559,563,567,571,575,579,583,587,591,595,599,603,607,611,615,619,623,627,632,636,640,644,648,652,656,660,664,668,673,677,681,685,689,693,697,701],{"__ignoreMap":174},[179,528,529],{"class":181,"line":182},[179,530,185],{},[179,532,533],{"class":181,"line":188},[179,534,192],{"emptyLinePlaceholder":191},[179,536,537],{"class":181,"line":195},[179,538,198],{},[179,540,541],{"class":181,"line":201},[179,542,204],{},[179,544,545],{"class":181,"line":207},[179,546,210],{},[179,548,549],{"class":181,"line":213},[179,550,216],{},[179,552,553],{"class":181,"line":219},[179,554,222],{},[179,556,557],{"class":181,"line":225},[179,558,192],{"emptyLinePlaceholder":191},[179,560,561],{"class":181,"line":230},[179,562,233],{},[179,564,565],{"class":181,"line":236},[179,566,239],{},[179,568,569],{"class":181,"line":242},[179,570,245],{},[179,572,573],{"class":181,"line":248},[179,574,251],{},[179,576,577],{"class":181,"line":254},[179,578,257],{},[179,580,581],{"class":181,"line":260},[179,582,263],{},[179,584,585],{"class":181,"line":266},[179,586,269],{},[179,588,589],{"class":181,"line":272},[179,590,275],{},[179,592,593],{"class":181,"line":278},[179,594,281],{},[179,596,597],{"class":181,"line":284},[179,598,192],{"emptyLinePlaceholder":191},[179,600,601],{"class":181,"line":289},[179,602,292],{},[179,604,605],{"class":181,"line":295},[179,606,275],{},[179,608,609],{"class":181,"line":300},[179,610,303],{},[179,612,613],{"class":181,"line":306},[179,614,309],{},[179,616,617],{"class":181,"line":312},[179,618,315],{},[179,620,621],{"class":181,"line":318},[179,622,192],{"emptyLinePlaceholder":191},[179,624,625],{"class":181,"line":323},[179,626,337],{},[179,628,629],{"class":181,"line":329},[179,630,631],{},"        s := make([]byte, 52428800)\n",[179,633,634],{"class":181,"line":334},[179,635,349],{},[179,637,638],{"class":181,"line":340},[179,639,355],{},[179,641,642],{"class":181,"line":346},[179,643,361],{},[179,645,646],{"class":181,"line":352},[179,647,367],{},[179,649,650],{"class":181,"line":358},[179,651,192],{"emptyLinePlaceholder":191},[179,653,654],{"class":181,"line":364},[179,655,378],{},[179,657,658],{"class":181,"line":370},[179,659,315],{},[179,661,662],{"class":181,"line":375},[179,663,192],{"emptyLinePlaceholder":191},[179,665,666],{"class":181,"line":381},[179,667,337],{},[179,669,670],{"class":181,"line":386},[179,671,672],{},"        s := make([]byte, 104587600)\n",[179,674,675],{"class":181,"line":391},[179,676,349],{},[179,678,679],{"class":181,"line":396},[179,680,355],{},[179,682,683],{"class":181,"line":402},[179,684,361],{},[179,686,687],{"class":181,"line":407},[179,688,367],{},[179,690,691],{"class":181,"line":412},[179,692,425],{},[179,694,695],{"class":181,"line":417},[179,696,431],{},[179,698,699],{"class":181,"line":422},[179,700,315],{},[179,702,703],{"class":181,"line":428},[179,704,281],{},[14,706,707],{},"Yeni kodu çalıştırdığımızda şu sonucu alırız:",[14,709,710],{},[489,711],{"alt":174,"src":712},"\u002Fimages\u002Fgarbage-collection-ve-golang\u002Fimage-2.avif",[14,714,715,716,718,719,721],{},"Benzer miktarda toplam ayrılmış hafıza değerleri görüyoruz, fakat anlık ayrılan hafıza başlangıçtaki sıfır değerine yakındır. ",[176,717,475],{}," değişkenini ",[176,720,471],{}," döngüsünün içinde tanımladığımız ve döngüden çıkıldığında artık bu değişkene erişim kalmadığı için Go runtime'ı onu çöp toplama sürecine soktu ve hafızayı boşalttı. Yani Go, değişkenlerin kapsamlarını (scope) dikkate alarak nesnelerin ömrünü hesaplar ve artık kullanılmayacaksa hafıza alanını boşaltır.",[14,723,724],{},"Özyinelemeli (recursive) fonksiyonlar olmadıkça, fonksiyonlardaki yerel değişkenlerin kapladıkları yer Go için büyük bir sorun teşkil etmeyecektir.",[54,726],{},[161,728,730],{"id":729},"global-değişken-tanımlamanın-gc-yükü","Global Değişken Tanımlamanın GC Yükü",[14,732,733,734,736],{},"Şimdi kodumuzu biraz daha değiştirelim. Bu sefer ",[176,735,471],{}," döngüsü içerisindeki yerel değişken tanımlamasını kaldıralım ve bu değişkeni en yukarıda paket seviyesinde (global) tanımlayalım:",[169,738,740],{"className":171,"code":739,"language":173,"meta":174,"style":174},"package main\n\nimport (\n    \"fmt\"\n    \"runtime\"\n    \"time\"\n)\n\nvar s []byte\n\nfunc printStats(memory runtime.MemStats) {\n    runtime.ReadMemStats(&memory)\n    fmt.Println(\"Memory Allocation       :\", memory.Alloc)\n    fmt.Println(\"Memory Total Allocation :\", memory.TotalAlloc)\n    fmt.Println(\"Memory Heap Allocation  :\", memory.HeapAlloc)\n    fmt.Println(\"Memory NumGC            :\", memory.NumGC)\n    fmt.Println(\"**********************************\")\n    fmt.Print(\"\\n\")\n}\n\nfunc main() {\n    fmt.Print(\"\\n\")\n    var memory runtime.MemStats\n    fmt.Println(\"************* START **************\")\n    printStats(memory)\n\n    for i := 0; i \u003C 10; i++ {\n        s = make([]byte, 52428800)\n        if s == nil {\n            fmt.Println(\"Operation failed!\")\n        }\n    }\n\n    fmt.Println(\"********* ALLOCATE 50M ***********\")\n    printStats(memory)\n\n    for i := 0; i \u003C 10; i++ {\n        s = make([]byte, 104587600)\n        if s == nil {\n            fmt.Println(\"Operation failed!\")\n        }\n    }\n    time.Sleep(3 * time.Second)\n    fmt.Println(\"********* ALLOCATE 100 M *********\")\n    printStats(memory)\n}\n",[176,741,742,746,750,754,758,762,766,770,774,779,783,787,791,795,799,803,807,811,815,819,823,827,831,835,839,843,847,851,855,859,863,867,871,875,879,883,887,891,895,899,903,907,911,915,919,923],{"__ignoreMap":174},[179,743,744],{"class":181,"line":182},[179,745,185],{},[179,747,748],{"class":181,"line":188},[179,749,192],{"emptyLinePlaceholder":191},[179,751,752],{"class":181,"line":195},[179,753,198],{},[179,755,756],{"class":181,"line":201},[179,757,204],{},[179,759,760],{"class":181,"line":207},[179,761,210],{},[179,763,764],{"class":181,"line":213},[179,765,216],{},[179,767,768],{"class":181,"line":219},[179,769,222],{},[179,771,772],{"class":181,"line":225},[179,773,192],{"emptyLinePlaceholder":191},[179,775,776],{"class":181,"line":230},[179,777,778],{},"var s []byte\n",[179,780,781],{"class":181,"line":236},[179,782,192],{"emptyLinePlaceholder":191},[179,784,785],{"class":181,"line":242},[179,786,233],{},[179,788,789],{"class":181,"line":248},[179,790,239],{},[179,792,793],{"class":181,"line":254},[179,794,245],{},[179,796,797],{"class":181,"line":260},[179,798,251],{},[179,800,801],{"class":181,"line":266},[179,802,257],{},[179,804,805],{"class":181,"line":272},[179,806,263],{},[179,808,809],{"class":181,"line":278},[179,810,269],{},[179,812,813],{"class":181,"line":284},[179,814,275],{},[179,816,817],{"class":181,"line":289},[179,818,281],{},[179,820,821],{"class":181,"line":295},[179,822,192],{"emptyLinePlaceholder":191},[179,824,825],{"class":181,"line":300},[179,826,292],{},[179,828,829],{"class":181,"line":306},[179,830,275],{},[179,832,833],{"class":181,"line":312},[179,834,303],{},[179,836,837],{"class":181,"line":318},[179,838,309],{},[179,840,841],{"class":181,"line":323},[179,842,315],{},[179,844,845],{"class":181,"line":329},[179,846,192],{"emptyLinePlaceholder":191},[179,848,849],{"class":181,"line":334},[179,850,337],{},[179,852,853],{"class":181,"line":340},[179,854,343],{},[179,856,857],{"class":181,"line":346},[179,858,349],{},[179,860,861],{"class":181,"line":352},[179,862,355],{},[179,864,865],{"class":181,"line":358},[179,866,361],{},[179,868,869],{"class":181,"line":364},[179,870,367],{},[179,872,873],{"class":181,"line":370},[179,874,192],{"emptyLinePlaceholder":191},[179,876,877],{"class":181,"line":375},[179,878,378],{},[179,880,881],{"class":181,"line":381},[179,882,315],{},[179,884,885],{"class":181,"line":386},[179,886,192],{"emptyLinePlaceholder":191},[179,888,889],{"class":181,"line":391},[179,890,337],{},[179,892,893],{"class":181,"line":396},[179,894,399],{},[179,896,897],{"class":181,"line":402},[179,898,349],{},[179,900,901],{"class":181,"line":407},[179,902,355],{},[179,904,905],{"class":181,"line":412},[179,906,361],{},[179,908,909],{"class":181,"line":417},[179,910,367],{},[179,912,913],{"class":181,"line":422},[179,914,425],{},[179,916,917],{"class":181,"line":428},[179,918,431],{},[179,920,921],{"class":181,"line":434},[179,922,315],{},[179,924,925],{"class":181,"line":439},[179,926,281],{},[14,928,929],{},[489,930],{"alt":174,"src":931},"\u002Fimages\u002Fgarbage-collection-ve-golang\u002Fimage-3.avif",[14,933,934],{},"Global değişken tanımladığımızda çöp toplayıcının daha az çalıştığını ve anlık bellek kullanımının (Memory Allocation) ilk durumun yaklaşık 3 katı olduğunu görürüz.",[57,936,938],{"id":937},"neden-böyle-oldu-kaçış-analizi","Neden Böyle Oldu? (Kaçış Analizi)",[14,940,941,942,944],{},"Go derleyicisi, derleme aşamasında hangi değişkenlerin stack alanında kalacağını, hangilerinin heap alanına taşınacağını belirlemek için ",[18,943,39],{}," yapar.",[14,946,947],{},"Bir değişkeni global (paket düzeyinde) tanımladığımızda, o değişken uygulamanın ömrü boyunca hayatta kalır. Bu durum onu çöp toplayıcı için kalıcı bir kök referans (GC Root) haline getirir. Global değişkene atanan değer ezilse dahi, Go GC'si (GOGC ayarları gereği) bu tür global referansları tarayıp temizleme konusunda yerel değişkenlere göre çok daha temkinli davranır ve belleği hemen iade etmeyebilir.",[161,949,951],{"id":950},"kıssadan-hisse","Kıssadan Hisse",[14,953,954],{},"Garbage Collector'ün işini düzgün yapabilmesi için değişkenlerimizin ömrünü gereksiz yere uzatmamalı ve işleri bittiğinde kapsam (scope) dışına çıkmalarını sağlamalıyız. Çöp toplayıcının verimli çalışması için saatlerce ekstra kod yazmamıza gerek yoktur; değişken sınırlarını olabildiğince dar tutarsak gerisini Go bizim yerimize halledecektir.",[956,957,959],"h5",{"id":958},"bu-yazıda-yapılan-değişiklikler","Bu Yazıda Yapılan Değişiklikler",[22,961,962,965],{},[25,963,964],{},"21.06.2026: Global değişken kullanımında GC'nin davranış farkı \"Kaçış Analizi (Escape Analysis)\" ve \"GC Kökleri (GC Roots)\" kavramlarıyla teknik olarak açıklandı. İmla hataları (STACK'da -> stack'te, stacke'e -> stack'e vb.) ve klavye hataları (aurılan -> ayrılan, basıyorurz -> basıyoruz vb.) giderildi. Kapak fotoğrafı telif satırları kaldırıldı. Karşılaştırma tablosu ve özet bloğu eklendi.",[25,966,967],{},"11.05.2022: Yazı özeti düzenlendi.",[969,970,971],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":174,"searchDepth":188,"depth":188,"links":973},[974,975,976,977,980],{"id":59,"depth":195,"text":60},{"id":163,"depth":188,"text":164},{"id":502,"depth":188,"text":503},{"id":729,"depth":188,"text":730,"children":978},[979],{"id":937,"depth":195,"text":938},{"id":950,"depth":188,"text":951},[982],"technical",null,"2021-10-01","Go (Golang) dilinde Garbage Collection (Çöp Toplama) süreci, bellek yönetimi (heap vs stack), kaçış analizi (escape analysis) ve bellek optimizasyonu.",false,"md","\u002Fimages\u002Fhero\u002Fgo-gc.avif",{},"\u002Ftr\u002Fgarbage-collection-ve-golang",{"title":6,"description":985},"garbage-collection-ve-golang","tr\u002Fgarbage-collection-ve-golang",[173,995],"golang","2026-06-21","HKxBSIwshzWLMhkLzAByBUeIq0kAES7PnKSJR2nzhNM",{"prev":999,"next":1002,"others":1005,"lucky":1126,"readingTime":213},{"path":1000,"title":1001},"\u002Ftr\u002Fcommand-tasarim-deseni-nedir","Command Tasarım Deseni Nedir?",{"path":1003,"title":1004},"\u002Ftr\u002Ftricolor-garbage-collection-algoritmasi-nedir","Tricolor Garbage Collection Algoritması Nedir?",[1006,1009,1012,1015,1018,1021,1024,1027,1030,1033,1036,1039,1042,1045,1048,1051,1054,1057,1060,1063,1066,1069,1072,1075,1078,1081,1084,1087,1090,1093,1096,1099,1102,1105,1108,1111,1114,1117,1120,1123],{"path":1007,"title":1008},"\u002Ftr\u002Fnext-js-on-bellegi-nasil-yenilenir-on-demand-cache-regeneration","Next.js Önbelleği Nasıl Yenilenir? \"On-Demand Cache Regeneration\"",{"path":1010,"title":1011},"\u002Ftr\u002Fes9-nedir-ecmascript-2018-nedir","ES9 Nedir? ECMAScript 2018 Nedir?",{"path":1013,"title":1014},"\u002Ftr\u002Fstate-tasarim-deseni-nedir","State Tasarım Deseni Nedir?",{"path":1016,"title":1017},"\u002Ftr\u002Fdocker-ile-redis-kurulumu","Docker ile Redis Kurulumu",{"path":1019,"title":1020},"\u002Ftr\u002Fphalcon-frameworkun-gelecegi","Phalcon Framework'ün Geleceği: Bir Devrin Sonu",{"path":1022,"title":1023},"\u002Ftr\u002Ffull-stack-proje-agaci","Full-Stack Proje Yol Haritası ve İçindekiler",{"path":1025,"title":1026},"\u002Ftr\u002Fdocker-swarm-nedir","Docker Swarm Nedir?",{"path":1028,"title":1029},"\u002Ftr\u002Fmerhabadunya","Merhaba Dünya",{"path":1031,"title":1032},"\u002Ftr\u002Fdigital-oceanda-vps-kurulumu","DigitalOcean'da VPS (Droplet) Kurulumu: Adım Adım Rehber",{"path":1034,"title":1035},"\u002Ftr\u002Fcomposite-tasarim-deseni-nedir","Composite Tasarım Deseni Nedir?",{"path":1037,"title":1038},"\u002Ftr\u002Fes15-nedir-ecmascript-2024-nedir","ES15 nedir? ECMAScript 2024 nedir?",{"path":1040,"title":1041},"\u002Ftr\u002Fopenlitespeed-ve-litespeed-enterprisei-reverse-proxy-olarak-kullanmak","OpenLiteSpeed ve LiteSpeed Enterprise Sunucularını Reverse Proxy Olarak Kullanmak",{"path":1043,"title":1044},"\u002Ftr\u002Fcodeserver-nedir-codeserver-nasil-kurulur","Code-Server Nedir? Bulutta VS Code Geliştirme Ortamı Kurulumu",{"path":1046,"title":1047},"\u002Ftr\u002Fmerhaba-tailwind-css","Merhaba Tailwind CSS",{"path":1049,"title":1050},"\u002Ftr\u002Fes11-nedir-ecmascript-2020-nedir","ES11 Nedir? ECMAScript 2020 Nedir?",{"path":1052,"title":1053},"\u002Ftr\u002Fes16-nedir-ecmascript-2025-nedir","ES16 nedir? ECMAScript 2025 nedir?",{"path":1055,"title":1056},"\u002Ftr\u002Fgo-veri-tipleri-string-integer-float-complex-boolean-ve-array","Go Veri Tipleri - String, Integer, Float, Complex, Boolean ve Array",{"path":1058,"title":1059},"\u002Ftr\u002Fstrategy-tasarim-deseni-nedir","Strategy Tasarım Deseni Nedir?",{"path":1061,"title":1062},"\u002Ftr\u002Fubuntu-20-04-uzerinde-cyberpanel-kurulumu","Ubuntu 20.04 üzerinde CyberPanel kurulumu",{"path":1064,"title":1065},"\u002Ftr\u002Fes17-nedir-ecmascript-2026-nedir","ES17 nedir? ECMAScript 2026 nedir?",{"path":1067,"title":1068},"\u002Ftr\u002Fes10-nedir-ecmascript-2019-nedir","ES10 Nedir? ECMAScript 2019 Nedir?",{"path":1070,"title":1071},"\u002Ftr\u002Fgo-veri-tipleri-struct","Go Veri Tipleri: Struct",{"path":1073,"title":1074},"\u002Ftr\u002Fes12-nedir-ecmascript-2021-nedir","ES12 Nedir? ECMAScript 2021 Nedir?",{"path":1076,"title":1077},"\u002Ftr\u002Ftasarim-kaliplari-design-patterns-abstract-factory-nedir","Abstract Factory Tasarım Deseni Nedir?",{"path":1079,"title":1080},"\u002Ftr\u002Fgo-slice-veri-tipi","Go Veri Tipleri: Slice",{"path":1082,"title":1083},"\u002Ftr\u002Fvue-js-nedir","Vue.js Nedir? Yeni Başlayanlar İçin Rehber",{"path":1085,"title":1086},"\u002Ftr\u002Fdocker-ile-mongodb-kurulumu","Docker ile MongoDB Kurulumu",{"path":1088,"title":1089},"\u002Ftr\u002Fapi-gateway-nedir","API Gateway Nedir? Ne İşe Yarar?",{"path":1091,"title":1092},"\u002Ftr\u002Fvue-3-hakkinda-bilmeniz-gerekenler-yenilikler","Vue 3 Hakkında Bilmeniz Gerekenler ve Yenilikler",{"path":1094,"title":1095},"\u002Ftr\u002Fprototype-tasarim-deseni-nedir","Prototype Tasarım Deseni Nedir?",{"path":1097,"title":1098},"\u002Ftr\u002Fmediator-tasarim-deseni-nedir","Mediator Tasarım Deseni Nedir?",{"path":1100,"title":1101},"\u002Ftr\u002Fdesign-patterns-tasarim-desenleri-nedir","Design Patterns \u002F Tasarım Desenleri nedir?",{"path":1103,"title":1104},"\u002Ftr\u002Frest-api-dokumantasyonu-nasil-yapilir","REST Api Dokümantasyonu Nasıl Oluşturulur?",{"path":1106,"title":1107},"\u002Ftr\u002Ftailwind-css-just-in-time-modu","Tailwind CSS Just-in-Time (JIT) Modu Nedir?",{"path":1109,"title":1110},"\u002Ftr\u002Fubuntu-guncellemesi-sonrasi-cyberpanele-ulasilamama-sorunlarini-giderme","Ubuntu Güncellemesi Sonrası CyberPanel'e Ulaşılamama Sorunlarını Giderme",{"path":1112,"title":1113},"\u002Ftr\u002Fes8-nedir-ecmascript-2017-nedir","ES8 Nedir? ECMAScript 2017 Nedir?",{"path":1115,"title":1116},"\u002Ftr\u002Fdocker-ile-mariadb-kurulumu","Docker ile MariaDB Kurulumu",{"path":1118,"title":1119},"\u002Ftr\u002Fiterator-tasarim-deseni-nedir","Iterator Tasarım Deseni Nedir?",{"path":1121,"title":1122},"\u002Ftr\u002Fnostalji-ibibik-online","Nostalji: İbibik Online (1998'den Bir Web Macerası)",{"path":1124,"title":1125},"\u002Ftr\u002Froot-yetkisi-olmayan-kullanici-ssh-baglantisini-ssh-baglantisini-ssh-anahtari-ile-nasil-kurabilir","Root yetkisi olmayan kullanıcı, SSH bağlantısını, SSH anahtarı ile nasıl kurabilir?",{"path":1088,"title":1089},[1128,1130,1134,1136],{"path":1070,"title":1071,"date":1129},"2021-10-14",{"path":1131,"title":1132,"date":1133},"\u002Ftr\u002Fgo-veri-tipleri-map","Go Veri Tipleri - Map","2021-10-13",{"path":1079,"title":1080,"date":1135},"2021-10-10",{"path":1055,"title":1056,"date":1135},[1138,1140,1144],{"path":1091,"title":1092,"date":1139},"2021-07-24",{"path":1141,"title":1142,"date":1143},"\u002Ftr\u002Frestapi-ve-hateoas-kavrami","RestApi ve HATEOAS Kavramı","2021-02-24",{"path":1052,"title":1053,"date":1145},"2026-06-20",1782142006478]