Bellek yönetimi
Otomatik Bellek Yönetimi > Çöp Toplama (Garbage Collection) > Referans Sayımı (Reference Counting)

Referans sayma ilgili tahsise yapılan her bir referansın sayılması ve referansların hepsinin sıfıra ulaşması durumunda tahsisin serbest bırakılmasına dayanır. Bu teknikte her referans kendisine referans eden bir sayma verisi bulundurur. Bu sayma verisi referans her kopyalandığında artırılır ve kopya her yok edildiğinde azaltılır. Referans sayma verisi sıfıra ulaştığında tahsisi kullanan bir program noktası olmadığından serbest bırakılır.
Referans sayma çöp toplama takibinde olduğu gibi doğrudan derleyici tarafından otomatik bir şekilde gerçekleştirilebilir ya da yazılım geliştirici tarafından ilgili bölümlerde referans sayma gerçekleştirilebilir.
Referans sayma deterministik bir çöp toplama performansı sergiler. Bunun nedeni program yürütülürken bir referansın oluşturulma, kopyalama ve serbest bırakılma noktaları her zaman sabit olduğundan referansın serbest bırakılma işlemi her zaman aynı algoritma adımında gerçekleşir.
Referans sayma için kullanılan sayma verisi çalışma zamanında ek bellek ayak izi anlamına gelir. Bununla birlikte referans sayma işlemi algoritmaya göre önemli miktarda çalışma zamanı yükü oluşturabilir. Bununla birlikte bazı problemlere sahiptir, bu problemlerin yok edilmesi amacıyla çeşitli yöntemler uygulanmaktadır ve bu yöntemler performansa olumsuz etki edebilmektedir.
Referans saymanın atomiklik (atomicity) sergilemesi gerekmektedir. Çok iş parçacıklı bir ortamda bir referansın aynı anda kopyalanması durumunda referans sayma doğru bir şekilde gerçekleşmeyebilir, bunu önlemek için referans sayma atomik bir şekilde gerçekleştirilmelidir. Bu atomiklik çok iş parçacıklı bir senaryo olmadığı durumlarda dahi küçük de olsa bir çalışma zamanı ek yükü oluşturur.
Referansın sayma verisi üstünde işlem gerektirecek herhangi bir durumun iş parçacıkları tarafından çok fazla tekrarlanması bu atomikliğin programın toplam çalışma süresinin önemli bir bölümünü oluşturmasına neden olabilir.
Referans saymanın diğer bir sorunu döngüselliktir. Örneğin iki referansın birbirlerine referans vermesi durumunda referans sayısının asla sıfırlanmadığı bir döngü oluşturulabilir, bu önlemek için çeşitli döngü algılama algoritmaları vardır.
Referans sayma çeşitli şekillerde uygulanabilir ve bu uygulamaların kendilerine has dezavantajları olabilir. Bazı referans sayma uygulamalarında referans sayma verisi sıfırlandığında tahsisin direkt serbest bırakılması yerine serbest bırakılmayı bekleyen tahsislerin bulunduğu bir bölümde listelenebilir ve periyodik olarak bu listedeki tahsisler serbest bırakılabilir.
Bir referans sayma verisinin sıfıra ulaşılması durumunda yok edilen tahsis de bir referans ise, bu sıralı bir referans sayma başlatabilir ve belirli durumlarda pek çok referansın sayma verisi sıfıra ulaştığından sıralı ve uzun bir serbest bırakmanın tetiklenmesine yol açabilir.
#include <iostream>
#include <string>
#include <memory>

struct Car {
    std::string brand;
    std::string model;
};

int main() {
    {
        // ptr heap tahsisli bir Car sınıfı üstünde referans sayımı gerçekleştiriyor
        // tahsis ptr ile birlikte 1 referansa sahip
        std::shared_ptr<Car> ptr(new Car{"Ford", "GT40"});
        
        {
            // ptr2 artık ptr'nin tahsisine işaret ediyor
            // tahsisin referans sayısı 2'ye ulaştı
            std::shared_ptr<Car> ptr2{ ptr };

            std::cout << ptr2->brand << " - " << ptr2->model << std::endl;

        } // ptr2 kapsam dışı kaldığından referans bir eksildi lakin serbest bırakılmadı
          // halen bir referans daha var, ptr tahsise işaret ediyor

    } // ptr kapsam dışı kaldı, referans sayısı 0 olduğundan tahsis serbest bırakıldı

    return EXIT_SUCCESS;
}