Çöp toplama, sahiplik ve referans sayımının hız, gecikme ve güvenlik üzerindeki etkilerini öğrenin—ve hedeflerinize uygun dili nasıl seçeceğinizi keşfedin.

Bellek yönetimi, bir programın bellek isteme, kullanma ve geri verme kuralları ve mekanizmalarıdır. Her çalışan program değişkenler, kullanıcı verisi, ağ tamponları, görüntüler ve ara sonuçlar gibi şeyler için belleğe ihtiyaç duyar. Bellek sınırlı ve işletim sistemi ile diğer uygulamalarla paylaşıldığı için, diller kimin bu belleği serbest bırakmaktan sorumlu olduğunu ve ne zaman bunun yapılacağını belirlemek zorundadır.
Bu kararlar, insanların çoğunun önem verdiği iki sonucu şekillendirir: bir programın ne kadar hızlı hissettirdiği ve baskı altındayken ne kadar güvenilir davrandığı.
Performans tek bir sayı değildir. Bellek yönetimi şu yönleri etkileyebilir:
Hızlı tahsis yapan ama bazen temizlemek için duraklayan bir dil kıyas testlerinde iyi görünebilir ama etkileşimli uygulamalarda titrek bir his verebilir. Duraklamalardan kaçınan başka bir model ise sızıntıları ve ömür hatalarını önlemek için daha dikkatli tasarım gerektirebilir.
Güvenlik, bellekle ilgili hataları önlemeyle ilgilidir; örneğin:
Birçok yüksek profilli güvenlik sorunu, use-after-free veya tampon taşmaları gibi bellek hatalarından kaynaklanır.
Bu rehber, popüler dillerin kullandığı ana bellek modellerinin teknik olmayan bir turudur: hangi hedefleri optimize ettikleri ve birini seçtiğinizde kabul ettiğiniz takaslar.
Bellek, programınızın çalışırken verileri tuttuğu yerdir. Çoğu dil bunu iki ana alan etrafında organize eder: stack ve heap.
Stack'i görev için kullanılan düzenli bir yapışkan not yığını gibi düşünün. Bir fonksiyon başladığında, yerel değişkenleri için stack'te küçük bir “çerçeve” alır. Fonksiyon bittiğinde o çerçeve bir kerede kaldırılır.
Bu hızlı ve öngörülebilirdir—ama yalnızca boyutu bilinen ve ömrü fonksiyon çağrısıyla sınırlı değerler için çalışır.
Heap, ihtiyaç duyduğunuz süre boyunca nesneleri saklayabileceğiniz bir depo odası gibidir. Dinamik boyutlu listeler, dizeler veya programın farklı bölümleri arasında paylaşılan nesneler için uygundur.
Heap nesneleri tek bir fonksiyonun ömrünü aşabildiği için kilit soru şudur: kim onları serbest bırakmaktan sorumlu ve ne zaman? Bu sorumluluk bir dilin “bellek yönetimi modeli”dir.
Bir pointer veya referans, bir nesneye dolaylı erişim yoludur—depo odasındaki bir kutunun raf numarasını bilmek gibidir. Eğer kutu atılırsa ama raf numaranız hâlâ varsa, çöp veri okuyabilir veya çökme yaşayabilirsiniz (klasik use-after-free hatası).
Bir döngü içinde müşteri kaydı oluşturduğunuzu, bir mesaj biçimlendirdiğinizi ve onu attığınızı varsayın:
Bazı diller bu ayrıntıları gizler (otomatik temizleme), bazıları ise açığa çıkarır (elle serbest bırakma veya kimin sahiplik kuralına uyacağına dair kurallar). Makalenin geri kalanı bu tercihlerin hız, duraklamalar ve güvenlik üzerindeki etkilerini inceliyor.
Manuel bellek yönetimi, programcının açıkça bellek istemesi ve daha sonra serbest bırakması anlamına gelir. Pratikte bu C'deki malloc/free veya C++'daki new/delete gibi görünür. Hassas bir şekilde ne zaman bellek edinip iade edeceğinizi kontrol etmeniz gereken sistem programlamasında hâlâ yaygındır.
Genellikle bir nesne mevcut fonksiyon çağrısından daha uzun yaşayacaksa, dinamik olarak büyüyecekse (ör. yeniden boyutlanan bir tampon) veya donanım, işletim sistemi ya da ağ protokolleriyle uyumluluk için belirli bir düzen gerekiyorsa ayırma yapılır.
Arka planda çalışan bir çöp toplayıcı olmadığında sürpriz duraklamalar daha az olur. Özelleştirilmiş ayırıcılar, havuzlar veya sabit boyutlu tamponlarla birleştirildiğinde tahsis ve serbest bırakma son derece öngörülebilir hâle getirilebilir.
Manuel kontrol ayrıca ek yükü azaltabilir: izleme aşaması yok, yazma bariyerleri yok ve genellikle nesne başına daha az metadata bulunur. Kod dikkatle tasarlandığında sıkı gecikme hedeflerine ulaşabilir ve bellek kullanımını sıkı sınırlar içinde tutabilirsiniz.
Takas, bunun bedelidir—çalışma zamanı otomatik olarak engellemeyeceği hatalar yapabilirsiniz:
Bu hatalar çöküşe, veri bozulmasına ve güvenlik açıklarına neden olabilir.
Ekipler riski azaltmak için ham tahsis izin verilen yerleri daraltır ve şu desenlere güvenir:
std::unique_ptr)Manuel bellek yönetimi genellikle gömülü yazılım, gerçek zamanlı sistemler, OS bileşenleri ve performans-kritik kütüphaneler için güçlü bir seçimdir—burada sıkı kontrol ve öngörülebilir gecikme, geliştirici konforundan daha önemlidir.
Çöp toplama (GC) otomatik bellek temizlemedir: belleği sizin elle serbest bırakmanızı gerektirmek yerine çalışma zamanı nesneleri izler ve daha erişilemez olanları geri alır. Bu, davranış ve veri akışına odaklanmanızı sağlarken sistem çoğu tahsis ve serbest bırakma kararını yönetir.
Çoğu toplayıcı önce canlı nesneleri belirler, sonra kalanları geri alır.
İzleme (tracing) GC köklerden (stack değişkenleri, global referanslar, registerlar) başlar, referansları takip ederek erişilebilir olan her şeyi işaretler ve sonra heap'i tarayıp işaretlenmemiş nesneleri serbest bırakır. Hiçbir şey bir nesneye işaret etmiyorsa, o nesne toplanmaya aday olur.
Generational GC birçok nesnenin kısa ömürlü olduğu gözlemi üzerine kuruludur. Heap'i kuşaklara ayırır ve genç alanı sık sık toplar; bu genellikle daha ucuzdur ve genel verimliliği artırır.
Eşzamanlı (concurrent) GC toplamanın bazı bölümlerini uygulama iş parçacıklarıyla birlikte çalıştırır, uzun duraklamaları azaltmayı hedefler. Bu, program çalışırken bellek görünümünü tutarlı kılmak için daha fazla ek iş gerektirebilir.
GC genellikle manuel kontrolü çalışma zamanı işi ile takas eder. Bazı sistemler istikrarlı throughput'u önceliklendirir (saniyede çok iş) ama stop-the-world duraklamalar olabilir. Diğerleri gecikmeyi en aza indirir ama normal yürütme sırasında ek yük ekleyebilir.
GC, yaşam süresi hatası sınıfının çoğunu ortadan kaldırır (özellikle use-after-free) çünkü erişilebilir olduğu sürece nesneler geri alınmaz. Ayrıca unutulan serbest bırakmaların neden olduğu sızıntıları azaltır (ancak referansları gereğinden uzun tutarak yine de sızdırabilirsiniz). Sahipliğin manuel izlenmesinin zor olduğu büyük kod tabanlarında bu, yinelemeyi hızlandırır.
GC çalışma zamanları JVM (Java, Kotlin), .NET (C#, F#), Go ve tarayıcı/Node.js içindeki JavaScript motorlarında yaygındır.
Referans sayımı, her nesnenin ona işaret eden “sahip” sayısını takip ettiği bir stratejidir. Sayı sıfıra düştüğünde nesne hemen serbest bırakılır. Bu anlıklık sezgisel olabilir: nesneye artık erişilemediği anda bellek geri kazanılır.
Bir referansı kopyaladığınızda veya depoladığınızda sayaç artar; bir referans ortadan kalktığında azalır. Sıfıra ulaşınca temizlik tetiklenir.
Bu, kaynak yönetimini basit kılar: nesneler genellikle kullanmayı bıraktığınız ana yakın bir noktada bellek bırakır; bu da pik bellek kullanımını azaltabilir ve gecikmeli geri kazanımdan kaçınabilir.
Referans sayımı genellikle sürekli, sabit bir ek yük taşır: artırım/azaltım işlemleri birçok atama ve fonksiyon çağrısında gerçekleşir. Bu yük genellikle küçüktür ama her yerde olur.
Avantajı, bazı izleme çöp toplayıcılarının neden olduğu büyük stop-the-world duraklamalarının olmamasıdır. Gecikme genellikle daha dengelidir, ancak büyük nesne grafiklerinin son sahibini kaybettiği anda toplu serbest bırakma patlamaları hâlâ olabilir.
Referans sayımı, döngü içindeki nesneleri geri alamaz. Eğer A, B'yi ve B de A'yı işaret ediyorsa, her iki sayım da sıfırın üzerinde kalır; dışarıdan ulaşılamasa bile bu bir bellek sızıntısı yaratır.
Ekosistemler bunu birkaç yolla ele alır:
Sahiplik ve borç alma, derleyicinin dangling pointer, double-free ve birçok veri yarışını çalışma zamanı GC'sine ihtiyaç duymadan zorlaştırdığı bir modeldir; bu modele en yakın örnek Rust'tır.
Her değerin aynı anda tam olarak bir “sahibi” vardır. Sahip scope dışına çıktığında değer hemen ve öngörülebilir şekilde temizlenir. Bu, manuel temizlemeye benzer deterministik kaynak yönetimi sağlar (bellek, dosya tutamaçları, soketler) ama yanlış yapma yolları çok daha azdır.
Sahiplik taşınabilir de olabilir: bir değeri yeni bir değişkene atamak veya bir fonksiyona geçirmek sorumluluğu transfer edebilir. Bir taşımadan sonra eski bağlama kullanılamaz; bu da use-after-free'u yapı gereği engeller.
Borç verme, bir değeri sahip olmadan kullanmanıza izin verir.
Paylaşılan borç salt okunur erişime izin verir ve serbestçe kopyalanabilir.
Değiştirilebilir borç güncellemelere izin verir ama tek olmalıdır: varken aynı veri üzerinde ne okunabilir ne de yazılabilir. Bu "bir yazıcı ya da birçok okuyucu" kuralı derleme zamanında denetlenir.
Yaşam süreleri izlenerek derleyici, referanslarının ömrünü aşacak kodu reddedebilir ve birçok dangling-reference hatasını ortadan kaldırır. Aynı kurallar, eşzamanlı kodda birçok yarış durumunu da engeller.
Takas, öğrenme eğrisi ve bazı tasarım kısıtlarıdır. Veri akışını yeniden yapılandırmanız, sahiplik sınırlarını netleştirmeniz veya paylaşılan değiştirilebilir durum için özel tipler kullanmanız gerekebilir.
Bu model, temizleme ve düşük gecikme isteyen ama GC duraklamalarını istemeyen sistem kodu—servisler, gömülü, ağ bileşenleri ve performans-kritik parçalar—için çok uygundur.
Birçok kısa ömürlü nesne oluşturduğunuzda—bir ayrıştırıcıdaki AST düğümleri, bir oyun karesindeki varlıklar, bir web isteği sırasında geçici veriler—her nesneyi tek tek ayırıp serbest bırakmanın maliyeti çalışma zamanını domine edebilir. Arenalar (bölge), havuzlar bu durumda ince taneli serbest bırakmayı hızlı toplu yönetimle takas eden desenlerdir.
Bir arena, zaman içinde birçok nesne ayırdığınız ve sonra hepsini bir kerede serbest bıraktığınız bir bellek “bölgesidir”.
Her nesnenin yaşam süresini tek tek takip etmek yerine ömürleri belirli bir sınırla ilişkilendirirsiniz: “bu istek için tahsis edilenler” veya “bu fonksiyonu derlerken tahsis edilenler”.
Arenalar genellikle hızlıdır çünkü:
Bu verimi artırabilir ve sık serbest bırakmalar veya ayırıcı rekabeti ile oluşan gecikme sıçramalarını azaltabilir.
Arenalar ve havuzlar şunlarda görülür:
Ana kural basittir: bir referansın, onu oluşturan bölgenin ömrünü aşmasına izin vermeyin. Arena'da tahsis edilen bir şey globalde saklanır veya arena süresinden sonra döndürülürse use-after-free riski vardır.
Diller ve kütüphaneler bunu farklı şekillerde ele alır: bazen disiplini ve API'leri kullanırlar, bazen bölge sınırını tiplerde kodlayabilirler.
Arenalar ve havuzlar çöp toplamaya veya sahiplik modellerine alternatif değildir—genellikle tamamlayıcıdır. GC dillerinde sıcak yollar için obje havuzları kullanılır; sahiplik tabanlı dillerde ömürleri gruplamak için arenalar kullanılabilir. Dikkatle kullanıldığında, temizleme zamanını korurken varsayılan olarak hızlı tahsis sağlarlar.
Bir dilin bellek modeli performans ve güvenlik hikâyesinin yalnızca bir parçasıdır. Modern derleyiciler ve çalışma zamanları programınızı daha az tahsis edecek, daha erken serbest bırakacak ve gereksiz defter tutmayı önleyecek şekilde yeniden yazar. Bu yüzden “GC yavaştır” veya “manuel bellek en hızlıdır” gibi genellemeler gerçek uygulamalarda sık sık çökebilir.
Birçok tahsis yalnızca fonksiyonlar arası veri geçirmek içindir. Escape analizi ile derleyici, bir nesnenin mevcut scope'u aşmadığını kanıtlayabilir ve onu heap yerine stack üzerinde tutabilir.
Bu, bir heap tahsisini ve ilişkili maliyetleri (GC takibi, referans sayımı güncellemeleri, ayırıcı kilitleri) ortadan kaldırabilir. Yönetilen dillerde, küçük nesnelerin beklenenden daha ucuz olmasının büyük bir nedeni budur.
Derleyici bir fonksiyonu inline ettiğinde (çağrıyı fonksiyon gövdesiyle değiştirdiğinde), soyutlama katmanlarının içini “görme” imkanı doğar. Bu görünürlük şu optimizasyonlara izin verir:
İyi tasarlanmış API'ler optimizasyondan sonra “sıfır maliyetli” olabilir, kaynaktaki görünüm tahsis ağırlıklı olsa bile.
JIT çalışma zamanı gerçek üretim verilerini (hangi kod yolları sıcak, tipik nesne boyutları, tahsis örüntüleri) kullanarak optimize edebilir. Bu genellikle verimi iyileştirir ama ısınma süresi ve ara sıra yeniden derleme ya da GC için duraklamalar ekleyebilir.
Önden derleme daha çok öngörülebilir başlangıç ve daha sabit gecikme sağlar.
GC tabanlı çalışma zamanları heap boyutlandırma, duraklama hedefleri ve kuşak eşik değerleri gibi ayarlar sunar. Bunları, ölçülmüş veriler (ör. gecikme sıçramaları veya bellek baskısı) gösterdiğinde ayarlayın; ilk adım olarak değil.
Aynı görünen iki uygulama, gizli tahsis sayıları, geçici nesneler ve pointer takipleri bakımından farklı olabilir. Bu farklar optimizörler, ayırıcı ve önbellek davranışı ile etkileşir—bu yüzden performans karşılaştırmaları tahmin değil profil gerektirir.
Bellek yönetimi tercihleri sadece kod yazma şeklini değiştirmekle kalmaz—işin ne zaman yapıldığını, ne kadar bellek ayırmanız gerektiğini ve kullanıcıya nasıl hissettirdiğini değiştirir.
Verim (Throughput) birim zamanda ne kadar iş yaptığınızdır. Gece işlendiğinde 10 milyon kaydı işleyen bir toplu işlem düşünün: GC veya referans sayımı küçük bir ek yük getirse bile geliştiricinin üretkenliğini artırıyorsa toplamda en hızlı bitirme bu olabilir.
Gecikme (Latency) ise tek bir işlemin uçtan uca ne kadar sürdüğüdür. Bir web isteği için tek yavaş cevap kötü bir kullanıcı deneyimi oluşturur; ortalama verim yüksek olsa bile fark edilir. Belleği geri almak için zaman zaman duraklayan bir çalışma zamanı toplu işler için uygundur ama etkileşimli uygulamalarda rahatsız edicidir.
Daha büyük bir bellek ayak izi bulut maliyetlerini artırır ve programları yavaşlatabilir. Çalışma kümeniz CPU önbelleklerine sığmazsa CPU daha sık RAM'den veri bekler. Bazı stratejiler hız için ekstra bellek takas ederken (ör. serbest bırakılmış nesneleri havuzda tutmak), diğerleri daha az bellek için ek defter tutma yükü getirir.
Parçalanma kullanılmayan belleğin birçok küçük aralığa bölünmesi demektir—örneğin dağınık küçük park yerlerinde bir kamyon park etmeye çalışmak gibi. Ayırıcılar boş yer aramak için daha fazla zaman harcayabilir ve bellek büyüyebilir.
Önbellek yerleşimi (cache locality) ilgili verilerin yakın olması demektir. Havuz/arena tahsisi genellikle yerelliği iyileştirir; uzun ömürlü, karışık boyutlu nesnelerle dolu heap zaman içinde daha az önbellek-dostu olabilir.
Tutarlı yanıt sürelerine ihtiyaç varsa—oyunlar, ses uygulamaları, alım-satım sistemleri, gömülü/gerçek zamanlı kontrolcüler—“çoğunlukla hızlı ama arada yavaş” olmak, “biraz daha yavaş ama tutarlı” olmaktan daha kötüdür. Bu durumlarda öngörülebilir serbest bırakma desenleri ve tahsisler üzerinde sıkı kontrol önem kazanır.
Bellek hataları sadece "geliştirici hatası" değildir. Gerçek sistemlerde bunlar güvenlik sorunlarına dönüşür: ani çöküşler (denial of service), yanlışlıkla veri sızması (serbest bırakılmış veya başlatılmamış bellek okunması) ya da saldırganların programı istenmeyen kod çalıştırmaya zorlayabileceği durumlar.
Farklı bellek yönetimi stratejileri farklı şekillerde başarısız olur:
Eşzamanlılık tehdit modelini değiştirir: bir iş parçacığında “uygun” olan bellek, başka bir iş parçacığında serbest bırakılıp değiştirildiğinde tehlikeli olabilir. Paylaşımı sınırlayan veya açık senkronizasyon gerektiren modeller, bozulma, veri sızıntısı ve aralıklı çöküş olasılığını azaltır.
Hiçbir bellek modeli tüm riski ortadan kaldırmaz—mantık hataları (kimlik doğrulama hataları, güvensiz varsayılanlar, eksik doğrulama) hâlâ olur. Güçlü ekipler ek korumalar kullanır: testlerde sanitizer'lar, güvenli standart kütüphaneler, sıkı kod incelemesi, fuzzing ve unsafe/FFI kodu etrafında katı sınırlar. Bellek güvenliği saldırı yüzeyini büyük oranda azaltır ama garanti değildir.
Bellek sorunları, onları oluşturan değişiklik yakınında yakalandığında daha kolay düzeltilir. Anahtar önce ölçmek, sonra doğru araçlarla problemi daraltmaktır.
Önce hız mı yoksa bellek büyümesi mi peşinde olduğunuzu belirleyin.
Performans için duvar saati zamanı, CPU zamanı, tahsis hızını (byte/s) ve GC/ayırıcı zamanını ölçün. Bellek için pik RSS, durağan RSS ve nesne sayımlarını izleyin. Aynı iş yükünü tutarlı girdilerle çalıştırın; küçük varyasyonlar tahsis çalkantısını gizleyebilir.
Yaygın göstergeler: tek bir istek beklenenden çok daha fazla tahsis yapıyor veya trafikle birlikte bellek artıyor ama verim sabit kalıyor. Düzeltmeler genellikle tamponları yeniden kullanmak, kısa ömürlü nesneler için arena/havuz kullanmak ve daha az nesnenin hayatta kalmasını sağlamak için nesne grafiğini basitleştirmektir.
Minimal bir girdide yeniden üretin, en katı çalışma zamanı kontrollerini (sanitizer/GC doğrulama) etkinleştirin, sonra şunları yakalayın:
İlk düzeltmeyi bir deney olarak görün; değişikliğin tahsisleri azaltıp sabitlemediğini doğrulamak için ölçümleri yeniden çalıştırın—sorunu başka yere kaydırmadan. Takslar hakkında daha fazla yorum için bakınız /blog/performance-trade-offs-throughput-latency-memory-use.
Bir dil seçimi yalnızca sözdizimi ya da ekosistemle ilgili değildir—bellek modeli günlük geliştirme hızını, operasyonel riski ve gerçek trafiğe karşı performansın öngörülebilirliğini belirler.
Ürününüzün ihtiyaçlarını bellek stratejisine eşleyin ve şu pratik soruları yanıtlayın:
Modeli değiştiriyorsanız sürtünme planlayın: mevcut kütüphanelere çağrılar (FFI), karışık bellek sözleşmeleri, araç zinciri ve işe alım pazarı. Prototipler, duraklamalar, bellek büyümesi ve CPU yükü gibi gizli maliyetleri erken ortaya çıkarır.
Pratik bir yaklaşım, değerlendirdiğiniz ortamlarda aynı özelliği prototiplemek ve temsilci yük altında tahsis hızı, kuyruk sonu gecikmesi ve pik belleği karşılaştırmaktır. Ekipler bazen bu tür "elma-elma" değerlendirmeyi Koder.ai'da yapar: küçük bir React ön uç ve Go + PostgreSQL arka ucu hızla iskeletleyip istek şekillerini ve veri yapılarını yineleyerek GC tabanlı bir servisin gerçekçi trafik altında nasıl davrandığını görebilir (ve kodu dışa aktarabilirsiniz).
Bellek yönetimi, bir programın veriler (nesneler, dizeler, tamponlar gibi) için hafıza ayırma ve artık gerekmediğinde bunu serbest bırakma şeklidir.
Etkileri:
Stack (yığın) hızlı, otomatik ve fonksiyon çağrılarıyla bağlıdır: bir fonksiyon döndüğünde, onun stack çerçevesi topluca kaldırılır.
Heap esnek ve dinamik ya da uzun ömürlü veriler içindir; ancak ne zaman ve kim temizleyecek sorusuna bir strateji gerekir.
Kural olarak: kısa ömürlü, sabit boyutlu yerel değişkenler için stack; ömürleri veya boyutları öngörülemez olanlar için heap kullanılır.
Bir referans/pointer, koda bir nesneye dolaylı erişim sağlar. Tehlike, nesnenin belleği serbest bırakıldıktan sonra hâlâ ona işaret eden bir referansın kullanılmasıdır.
Bunun sonucunda:
Belleği açıkça ayırıp serbest bırakırsınız (ör. malloc/free, new/delete).
Aşağıdaki durumlarda kullanışlıdır:
Maliyeti: sahiplik ve ömürler dikkatlice yönetilmezse daha fazla hata riski.
Program iyi tasarlandığında manuel yönetim çok öngörülebilir gecikme sağlar çünkü arka planda çalışan bir GC döngüsü yoktur.
Optimize etmek için:
Ancak yanlış yapılırsa parçalanma, ayırıcı rekabeti veya çok küçük çok sayıda alloc/free çağrıları gibi maliyetli desenler kolayca oluşur.
Çöp toplama, artık erişilemeyen nesneleri bulan ve belleği geri alan otomatik temizlemedir.
Çoğu izleyici GC şu şekilde çalışır:
Bu genellikle use-after-free tarzı hataları azaltır ama çalışma zamanında ekstra iş yükü ekleyebilir ve toplayıcının tasarımına bağlı olarak duraklamalara neden olabilir.
Referans sayımı, bir nesneye kaç “sahip” (referans) olduğunu takip eder; sayım sıfıra düştüğünde nesne hemen temizlenir.
Artıları:
Eksileri:
Sahiplik/ödünç alma (ownership/borrowing), özellikle Rust ile ilişkilendirilen ve derleme zamanında kurallar uygulayarak birçok ömür hatasını önleyen bir modeldir.
Temel fikirler:
GC olmadan öngörülebilir temizleme sağlar, ama derleyici kurallarını karşılamak için veri akışını yeniden yapılandırmak gerekebilir.
Bir arena/bölge, birçok nesnenin tahsis edildiği ve sonra hepsinin bir kerede serbest bırakıldığı bir "alan"dır.
Faydaları:
Kullanışlı olduğu yerler: istek-başına tahsisler, oyunlar için per-frame tahsisleri, derleyici/parser geçici düğümleri.
Güvenlik kuralı: arena ömrünü aşan referanslara izin vermeyin; aksi takdirde use-after-free riski doğar.
Önce gerçekçi yük altında ölçüm yapın:
Araçlar:
Ekosistemler bunu zayıf referanslar veya döngü algılama gibi tekniklerle hafifletir.
GC ayarlarını sadece ölçülmüş bir sorunu işaretledikten sonra ayarlayın.