[linux-l] Erzwingen einer Garbage Collection

Volker Grabsch vog at notjusthosting.com
Mi Sep 27 12:50:40 CEST 2006


On Wed, Sep 27, 2006 at 01:18:49AM +0200, Olaf Radicke wrote:
> Ich hatte nicht alle Beiträge zum Thema Garbage Collection gelesen. Ich hatte 
> wenig zeit zum Lesen in den letzten Tagen.

me2, aber da auch ich einige Info inpetto habe, gebe ich sie hier
auch einfach mal ab, trotz der Gefahr, dass sowas ähnliches schonmal
geschrieben wurde.

> Hier ein paar Links, die zeigen das man auch mit Garbage Collection Kontrolle 
> über Speicherfreigabe hat (zu Mindesten bei C# / .NET):
[...]

Der Garbage-Collector von Ocaml ist auch ziemlich gut:
http://www.ocaml-tutorial.org/garbage_collection

Wohingegen der GC von Java einfach nur grauenvoll ist:
http://www.jwz.org/doc/java.html

Außerdem sollte man noch erwähnen, dass man in C++ auch sowas
wie einen ganz primitiven Garbage-Collector hat, wenn das überhaupt
den Namen verdient. Dort wird im Gegensatz zu Java ein Unterschied
zwischen Objekten und Pointern auf Objekte gemacht, und wenn man
auch Pointer verzichtet (was in jedem C++ Code ohne Rückreferenzen
möglich ist, d.h. in jedem Code, dessen Datenstrukturen nur Bäume
sind, und keine beliebigen Graphen). Dann macht der Compiler im
Prinzip "genau das, was man will":

    void funktion()
    {
        Klasse1 obj1;
        [..]
        Klasse2 obj2(param1, param2);

        obj1.machewas();
        obj2.machewas();

        [...]
    }

Am Ende werden obj1 und obj2 direkt entsorgt, d.h. Destruktor
aufgerufen. Speicher wird sowieso freigegeben, der liegt ja nur
auf dem Stack. Selbiges gilt auch für das Innere von Schleifen
*und* sogar für Klassen an sich:

    class Klasse1
    {
    private:
        string member1;
        Klasse2 member2;
        list<string> member3;
    public:
        [...]
    }

Der Destruktor von Klasse1 zerstört automatisch member1, member2
und soagr die Liste member3 (weil einfach deren Destruktor aufgerufen
wird).

Richtig schön einfach. Genauso gut wie Reference-Counting, nur dass
dies schon zur Compile-Zeit geschieht. Natürlich nur, solange man
ohne Pointer auskommt. Natürlich will man Objekte als Parameter
übergeben, ohne den ganzen Overhead, also als Pointer. C++ bietet
hier eine saubere Lösung namens "Referenzen". Hier wird nur die
Adresse übergeben, aber man kann es genauso behandeln wie ein
normales Objekt, ohne Pointer, und es ist klar, dass das Objekt
nicht entsorgt werden muss (sondern von der aufrufenden Funktion
irgendwann).

Ich schreibe das gerade aus eigener Erfahrung. Wir haben ein Projekt
zunächst in C begonnen, bekamen dann aber grünes Licht für C++.
Leider haben wir dummerweise zunächst im "alten Stil" weitergemacht,
mit vielen vielen Pointern. Jede Nachlässigkeit wird mit einem
Memory-Leak bestraft, und sogar Segfaults kommen vor. Wir sind gerade
dabei, alles auf Nicht-Pointer umzustellen. Das schöne dabei: Mit
einem Schlag werden sämtliche Memory-Leaks und Buffer-Overflows
beseitigt. Und interessanterweise ohne Garbage-Collector. Es wird
voraussichtlich nur ganz wenige Stellen geben, an denen Pointer
nötig sind, und die werden so dicht wie möglich abgeschnitten: In
einzelnen Funktionen, oder zumindest in einzelnen, übersichtlichen,
kleinen Klassen.

Das geht wiegesagt nur, weil alle Objekte bei uns einen trivialen
Lebenszyklus haben. Ich wollte damit nur zeigen, dass man in vielen
Projekten auch ohne GC auskommen kann, wenn sich schon der Compiler
darum kümmert. In Sprachen, die nur Pointer kennen (wie Java, Python,
...) ist das natürlich fast unmöglich.


Natürlich gibt es auch noch explizite GCs für C++, aber mit denen
kenne ich mich nicht so aus.


Viele Grüße,

    Volker

-- 
Volker Grabsch
---<<(())>>---
Administrator
NotJustHosting GbR



Mehr Informationen über die Mailingliste linux-l