RAII & GC
-
Morgen,
ich habe gerade gelesen, dass ein Vorteil eines GCs ist, dass er entscheiden kann wann er nicht mehr gebrauchten Speicher frei gibt. Auch wenn das schwachsinnig erscheint, ist es ja doch so, dass ein free() oder delete einiges an Zeit kosten kann. (Zumindest auf Windows) Warum ist das so? Letztlich kann das OS doch mindestens genau so gut entscheiden, wie es mit einer Freigabe umgehen möchte. (Und ob es danach umsortiert oder nicht etc.)
-
lulz schrieb:
Morgen,
ich habe gerade gelesen, dass ein Vorteil eines GCs ist, dass er entscheiden kann wann er nicht mehr gebrauchten Speicher frei gibt. Auch wenn das schwachsinnig erscheint, ist es ja doch so, dass ein free() oder delete einiges an Zeit kosten kann. (Zumindest auf Windows) Warum ist das so? Letztlich kann das OS doch mindestens genau so gut entscheiden, wie es mit einer Freigabe umgehen möchte. (Und ob es danach umsortiert oder nicht etc.)
Ein OS weiß nicht welchen Speicher eines Programmes es freigeben kann, daher macht es so etwas nur dann, wenn das Programm sowieso abgestürzt ist.
Und der Vorteil des GC ist nicht, daß er entscheiden kann, wann er nicht gebrauchten Speicher frei gibt, sondern daß man sich als Programmierer nicht mehr um die Freigabe von Speicher kümmern muß. Das macht der GC selbst.
In der Regel führt er ne Liste von Objekten und wenn die nicht mehr referenziert sind, dann sind die zur Freigabe freigegeben, dadurch weiß der GC welche Objekte er freigeben darf und welche nicht.ist es ja doch so, dass ein free() oder delete einiges an Zeit kosten kann. (Zumindest auf Windows) Warum ist das so?
Weil das Betriebssystemfunktionen sind, das erfordert einen Prozesswechsel, von der Anwendung zum OS.
-
Ein OS weiß nicht welchen Speicher eines Programmes es freigeben kann, daher macht es so etwas nur dann, wenn das Programm sowieso abgestürzt ist.
Ergänzung:
Oder wenn der User entscheidet, das ein Programm gekillt werden soll.
-
lulz schrieb:
ich habe gerade gelesen, dass ein Vorteil eines GCs ist, dass er entscheiden kann wann er nicht mehr gebrauchten Speicher frei gibt. Auch wenn das schwachsinnig erscheint, ist es ja doch so, dass ein free() oder delete einiges an Zeit kosten kann.
Der Zeitfaktor liegt darin, das ein GC vereinfacht gesagt die Objekte zu einem gemeinsamen Zeitpunkt frei gibt. Das kann lange dauern und meistens zu einem Zeitpunkt, an dem es gerade nicht recht ist (eigentlich nie).
Wenn du RAII benutzt, wird zwar auch Zeit für jedes Objekt benötigt, aber eben nicht auf einmal. Es ist sozusagen nur punktuell langsam und fällt nicht so auf.
-
Der GC gibt überhaupt keine Objekte frei. Er behält alle, die er noch braucht, und planiert bildlich gesprochen den Rest des Speichers einmal über. Eine Ausnahme sind Objekte mit Finalizern, die müssen tatsächlich "freigegeben" werden. Deshalb sollte man auch nicht unbedacht Finalizer schreiben.
Das ist das Grundprinzip eines Mark&Sweep-Collectors. In der Regel hat man noch Verschiebung von Objekten, die die Collection überlebt haben (Compacting GC). Das hat den Vorteil, dass das "Planieren" (und das Allozieren neuer Objekte) jeweils nur eine Zeigeraddition sind. Außerdem gibt es häufig Generational GCs, d.h. dass bei den meisten Collections nur die seit dem letzten Durchgang neu dazugekommenen Objekte betrachtet werden, wobei die überlebenden Objekte in die ältere "Generation" verschoben werden, die nur alle 100 Durchgänge oder so betrachtet wird. Hier zeigt sich auch nochmal, warum Finalizer eine schlechte Idee sind: Zu finalisierende Objekte überleben die nächste Collection grundsätzlich und gelten dann als langlebig.
Bei einem malloc/free-ähnlichen System, ob es nun mit Referenzzählung, manuell oder sonstwie funktioniert, ist dagegen die Freigabe und Allokation von Objekten eine nichttriviale Angelegenheit: Bei der Allokation muss ein freier Speicherblock gesucht und ggf. geteilt werden, bei der Freigabe muss ein Speicherblock ggf. mit seinen Nachbarn, sofern diese frei sind, verschmolzen werden.
tl;dr: Die Kosten des Freigebens sind gegenüber den Kosten des Findens und Verschiebens der erreichbaren Objekte vernachlässigbar.