Asıl cevap, güvenli ve verimli bir çöp toplama mekanizması oluşturmanın tek yolunun opak referanslar için dil düzeyinde desteğe sahip olmasıdır . (Ya da tam tersine, doğrudan bellek manipülasyonu için dil düzeyinde destek eksikliği .)
Java ve C #, değiştirilemeyen özel referans türlerine sahip olduklarından bunu yapabilir. Bu, çalışma zamanına yüksek performanslı bir GC uygulaması için çok önemli olan bellekteki ayrılmış nesneleri taşımak gibi şeyler yapma özgürlüğü verir .
Kayıt için, hiçbir modern GC uygulaması referans sayımı kullanmaz , bu tamamen kırmızı bir ringa balığıdır. Modern GC'ler, yeni tahsislerin temelde yığın tahsislerinin C ++ gibi bir dilde olduğu şekilde muamele edildiği ve daha sonra periyodik olarak hala canlı olan yeni tahsis edilen nesnelerin ayrı bir "kurtulan" alana ve tüm bir nesile taşındığı kuşak koleksiyonu kullanır. nesnelerin bir kerede serbest bırakılır.
Bu yaklaşımın avantajları ve dezavantajları vardır: Bunun tersi, GC'yi destekleyen bir dilde yığın tahsislerinin GC'yi desteklemeyen bir dilde yığın tahsisleri kadar hızlı olması ve olumsuz tarafı ise, tahrip edilmeden önce temizleme gerçekleştirmesi gereken nesnelerin de olmasıdır. ayrı bir mekanizma (örneğin, C # using
anahtar kelimesi) gerektirir veya temizleme kodları deterministik olmayan şekilde çalışır.
Yüksek performanslı bir GC'nin bir anahtarının, özel bir referans sınıfı için dil desteği olması gerektiğini unutmayın. C bu dil desteğine sahip değil ve asla olmayacak; C ++ operatörünün aşırı yüklenmesine sahip olduğundan, dikkatle yapılması gerekse de GC'd pointer tipini taklit edebilir. Aslında, Microsoft CLR (.NET çalışma zamanı) altında çalışacak olan C ++ lehçesini icat ettiğinde, Foo^
onları "C ++ tarzı referanslar" dan ayırmak için "C # tarzı başvuruları" (örneğin ) için yeni bir sözdizimi icat etmek zorunda kaldılar. (örneğin Foo&
).
C ++ 'ın sahip olduğu ve C ++ programcıları tarafından düzenli olarak kullanılan şey, gerçekten sadece referans sayma mekanizması olan akıllı işaretçilerdir . Referans sayımının "doğru" GC olduğunu düşünmezdim, ancak manuel bellek yönetiminden veya gerçek GC'den daha düşük performans karşılığında fakat aynı zamanda deterministik yıkım avantajıyla, aynı faydaların çoğunu sağlıyor.
Günün sonunda, cevap gerçekten bir dil tasarım özelliğine dayanıyor. C bir seçim yaptı, C ++, çoğu amaç için yeterince iyi alternatifler sunarken, C ile geriye dönük olarak uyumlu olmasını sağlayan bir seçim yaptı ve Java ve C #, C ile uyumlu olmayan ancak aynı zamanda yeterince iyi olan farklı bir seçim yaptı. çoğu amaç. Ne yazık ki, gümüş mermi yoktur, ancak farklı seçeneklere aşina olmak, şu anda oluşturmaya çalıştığınız program için doğru olanı seçmenize yardımcı olacaktır.