Sorunuzu ters çevirin. Asıl motive edici soru hangi koşullar altında çöp toplama maliyetlerini önleyebiliriz?
Öncelikle kapalı ne olduğu çöp toplama maliyetleri? İki ana maliyet var. İlk önce neyin canlı olduğunu belirlemelisiniz ; Bu potansiyel olarak çok fazla çalışma gerektirir. İkinci olarak, halen hayatta olan iki şey arasında tahsis edilmiş bir şeyi serbest bıraktığınızda oluşan delikleri sıkıştırmanız gerekir . Bu delikler boşuna. Ancak onları sıkıştırmak da pahalıdır.
Bu maliyetleri nasıl önleyebiliriz?
Açıkça, hiç bir zaman uzun ömürlü bir şey tahsis etmediğiniz , daha sonra kısa ömürlü bir şey tahsis etmediğiniz , ardından uzun ömürlü bir şey tahsis etmediğiniz bir depolama kullanım şekli bulabilirseniz , deliklerin maliyetini ortadan kaldırabilirsiniz. Depolama alanınızın bazı alt kümeleri için, ardından gelen her tahsisatın o depoda bir öncekinden daha kısa ömürlü olduğunu garanti ederseniz, o zaman bu depoda hiçbir zaman delik açılmaz.
Ancak, delik problemini çözdüysek, çöp toplama problemini de çözdük . Depoda hala canlı olan bir şeyin var mı? Evet. Daha uzun ömürlü olmadan önce her şey tahsis edildi mi? Evet - bu varsayım, delik olasılığını nasıl ortadan kaldırdığımızdır. Bu nedenle yapmanız gereken tek şey "canlı olan en son tahsisat mı?" Demek. ve biliyorsun ki her şey o depoda canlıdır.
Sonraki tahsisatların önceki tahsisattan daha kısa ömürlü olduğunu bildiğimiz bir dizi depolama tahsisatı var mı? Evet! Aktivasyon kareleri, yaratıldıkları sırayla yıkılır, çünkü yarattıkları aktivasyondan daima daha kısa ömürlüdürler.
Bu nedenle aktivasyon çerçevelerini yığında depolayabilir ve asla toplanmayacaklarını biliriz. Yığında herhangi bir çerçeve varsa, altındaki tüm çerçeve kümesi daha uzun ömürlüdür, bu nedenle toplanmaları gerekmez. Ve onlar yaratıldıkları sırayla imha edilecekler. Böylece çöp toplama maliyeti, aktivasyon çerçeveleri için elimine edilir.
Bu yüzden ilk önce yığında geçici havuzumuz var: çünkü bir hafıza yönetimi cezası vermeden yöntem aktivasyonunu uygulamanın kolay bir yoludur.
(Tabii ki, aktivasyon çerçevelerinde referanslar tarafından belirtilen hafızanın toplanmasının maliyeti de hala oradadır.)
Şimdi, aktivasyon çerçevelerinin öngörülebilir bir sırada imha edilmediği bir kontrol akış sistemi düşünün . Kısa ömürlü bir aktivasyon uzun ömürlü bir aktivasyona neden olabilirse ne olur? Tahmin edebileceğiniz gibi, bu dünyada artık aktivasyon toplama ihtiyacını ortadan kaldırmak için yığını kullanamazsınız. Aktivasyon seti tekrar delikler içerebilir.
C # 2.0 şeklinde bu özelliği vardır yield return
. Bir verim geri dönüşü yapan bir yöntem daha sonra - MoveNext'in bir sonraki çağrısında - ve bu olduğunda ne zaman olacağı tahmin edilemeyecek şekilde yeniden etkinleştirilecektir. Bu nedenle normal olarak yineleyici bloğunun aktivasyon çerçevesi için yığınta olacak olan bilgi, bunun yerine, numaralandırıcı toplandığında toplandığı çöpün bulunduğu yığınta depolanır.
Benzer şekilde, C # ve VB'nin sonraki sürümlerinde yer alan "async / await" özelliği, etkinliğin yöntemi "iyi" ve "devam ettiren" yöntemlerin eylemi sırasında iyi tanımlanmış noktalarda yöntemler oluşturmanıza izin verecektir. Aktivasyon çerçeveleri artık öngörülebilir bir şekilde yaratılmadığından ve imha edilmediğinden, yığında depolanan tüm bilgilerin yığın halinde depolanması gerekecektir.
Sadece on yıllardır kesin olarak düzenlenmiş bir biçimde oluşturulan ve tahrip olmuş aktivasyon çerçevelerine sahip dillerin modaya uygun olduğuna karar vermemiz bir kazadır. Modern diller giderek artan bir şekilde bu özellikten yoksun olduğundan, devam edenleri yığından ziyade çöp toplanan yığına yeniden yönlendiren daha fazla dil görmeyi bekliyoruz.