Funktionsweise MeixnerGC



  • Hi, mit shared_ptr hat man ja das Problem, dass man keine zirkularen Abhängikeiten auflösen kann und memory leaks bekommt. Mit Garbage Collectoren geht das dagegen sehr wohl. Jetzt wollte ich mir mal die Implementierung eines solchen anschauen und nachvollziehen wie ein GC funktioniert. Blicke aber noch nicht so ganz durch, obwohl der Code an und für sich recht überschaubar ist.

    Vielleicht kann mir einer von euch erklären wie dieser GC arbeitet?

    https://sourceforge.net/p/meixnergc/code/HEAD/tree/

    --> gc_ptr.h/cpp

    Z. B. anhand zweier Klassen A und B die sich gegenseitig verlinken:

    class ClassA
    {
    public:
        gc_ptr<ClassB> m_pClassB;
    };
    
    class ClassB
    {
    public:
        gc_ptr<ClassA> m_pClassA;
    };
    
    int main()
    {
        gc_ptr<ClassA> pClassA = new(gc) ClassA();
        gc_ptr<ClassB> pClassB = new(gc) ClassB();
        pClassA->m_pClassB = pClassB;
        pClassB->m_pClassA = pClassA;
        return 0;
    }
    

    Meinem jetzigen Verständnis nach arbeitet der GC intern mit mehreren verlinkten Listen. Eine dieser Listen beinhaltet alle MemObjects (welche von einer INode Klasse abgeleitet sind). Jedes Objekt auf dem Heap wird also über ein MemObject im GC registriert. Ein MemObject hat zudem eine Liste von gc_ptr die auf dieses Objekt verweisen. Auch gc_ptr sind von der INode Klasse abgeleitet.
    Zudem hat der GC noch eine Liste von Root gc_ptr. Ausgehend von diesen Root gc_ptr werden dann die noch erreichbaren Ojekte markiert und nicht markierte Objekte gelöscht.

    Wird einem gc_ptr also ein Objekt zugewiesen wird zunächst geprüft, ob der GC schon einen Root gc_ptr auf dieses Objekt hat. Falls nein wird der gc_ptr in die Liste der Root gc_ptr hinzugefügt. Falls doch landet er wohl in der gc_ptr Liste des zugehörigen MemObjects.

    Wie jetzt allerdings das Mark/Sweep funktioniert ist mir noch nicht so ganz klar. Mal angenommen der gc_ptr<ClassA> pClassA würde zerstört/resettet. Wie würde der GC z.B. feststellen, dass das ClassA Objekt noch durch den Member gc_ptr<ClassA> des pClassB Objektes verlinkt ist und noch nicht gelöscht werden darf? Jemand eine Idee?



  • Ich habe mir den Code von MeixnerGC nicht angesehen, aber ich denke es wird wohl so funktionieren: Jeder gc_ptr der im Speicherbereich eines dynamisch angeforderten Objekts liegt, gehört zu diesem Objekt. Und alle gc_ptr die zu keinem Objekt gehören sind Roots.

    Dazu muss die Library bloss die Adresse + Grösse von allen dynamisch erzeugten Objekten kennen. Und das macht sie indem sie den User zwingt den von ihr definierten placement new Operator zu verwenden (die "new (gc)" Sache).


Log in to reply