Speicherbereinigung bedeutet im Grunde nur, dass Ihre zugewiesenen Objekte automatisch freigegeben werden, sobald sie nicht mehr erreichbar sind.
Genauer gesagt, werden sie freigegeben, wenn sie für das Programm nicht mehr erreichbar sind , da Objekte, auf die zirkulär verwiesen wird, ansonsten niemals freigegeben würden.
Intelligente Zeiger beziehen sich nur auf jede Struktur, die sich wie ein gewöhnlicher Zeiger verhält, jedoch einige zusätzliche Funktionen enthält. Dazu gehören unter anderem die Freigabe, aber auch Copy-on-Write-Prüfungen, gebundene Schecks, ...
Wie Sie bereits ausgeführt haben, können jetzt intelligente Zeiger verwendet werden , um eine Form der Garbage Collection zu implementieren.
Aber der Gedankengang geht folgendermaßen:
- Garbage Collection ist eine coole Sache, da es praktisch ist und ich mich um weniger Dinge kümmern muss
- Deshalb: Ich möchte Müllabfuhr in meiner Sprache
- Wie kann ich GC in meine Sprache bringen?
Natürlich können Sie es von Anfang an so gestalten. C # wurde entwickelt , um Müll zu sammeln, also nur new
Ihr Objekt und es wird freigegeben, wenn die Verweise außerhalb des Gültigkeitsbereichs fallen. Wie das gemacht wird, liegt beim Compiler.
In C ++ war jedoch keine Garbage Collection vorgesehen. Wenn wir einen Zeiger zuweisen int* p = new int;
und dieser außerhalb des Gültigkeitsbereichs liegt, p
wird er vom Stapel entfernt, aber niemand kümmert sich um den zugewiesenen Speicher.
Jetzt haben Sie von Anfang an nur noch deterministische Destruktoren . Wenn ein Objekt den Bereich verlässt, in dem es erstellt wurde, wird sein Destruktor aufgerufen. In Kombination mit Vorlagen und Überladen von Operatoren können Sie ein Wrapper-Objekt entwerfen, das sich wie ein Zeiger verhält, jedoch Destruktorfunktionen zum Bereinigen der damit verbundenen Ressourcen (RAII) verwendet. Sie nennen dies einen intelligenten Zeiger .
Dies ist alles sehr spezifisch für C ++: Überladen von Operatoren, Vorlagen, Destruktoren, ... In dieser speziellen Sprachsituation haben Sie intelligente Zeiger entwickelt, um Ihnen den gewünschten GC bereitzustellen.
Wenn Sie jedoch von Anfang an eine Sprache mit GC entwerfen, handelt es sich lediglich um ein Implementierungsdetail. Sie sagen nur, dass das Objekt bereinigt wird und der Compiler dies für Sie erledigt.
Intelligente Zeiger wie in C ++ wären wahrscheinlich nicht einmal in Sprachen wie C # möglich, die überhaupt keine deterministische Zerstörung aufweisen (C # umgeht dies, indem es syntaktischen Zucker zum Aufrufen .Dispose()
bestimmter Objekte bereitstellt ). Nicht referenzierte Ressourcen werden schließlich vom GC zurückgefordert, aber es ist nicht definiert, wann genau dies geschieht.
Dies wiederum kann es dem GC ermöglichen, seine Arbeit effizienter zu erledigen. Wird in tiefer in die Sprache als intelligenter Zeiger gebaut, die oben drauf gesetzt werden, kann das .NET GC zB Speicheroperationen verzögern und sie in den Blöcken führen sie billiger zu machen oder sogar bewegen Speicher um zur Steigerung der Effizienz auf , wie oft Objekte abgerufen werden.