Auf den Punkt gebracht : Garbage Collectors verwenden keine Rekursion. Sie steuern lediglich die Verfolgung, indem sie im Wesentlichen zwei Sätze (die kombiniert werden können) verfolgen. Die Reihenfolge der Ablaufverfolgung und der Zellverarbeitung ist irrelevant, was eine erhebliche Freiheit bei der Implementierung zur Darstellung der Mengen bietet. Daher gibt es viele Lösungen, die in der Speichernutzung tatsächlich sehr billig sind. Dies ist wichtig, da der GC genau dann aufgerufen wird, wenn der Heap nicht mehr genügend Arbeitsspeicher hat. Die Dinge sind ein bisschen anders mit großen virtuellen Erinnerungen, als neue Seiten können einfach zugeordnet werden, und die ennemy ist der Mangel nicht von Raum, sondern von Daten fehlt
Lokalität .
Ich gehe davon aus, dass Sie überlegen , Müllsammler aufzuspüren, nicht die Referenzzählung, für die Ihre Frage anscheinend nicht zutrifft.
Die Frage konzentriert sich auf die Speicherkosten der Verfolgung , um einen Satz zu verfolgen: den Satz (für nicht verfolgt) von zugänglichen Speicherzellen, die noch Zeiger enthalten, die noch nicht verfolgt wurden. Dies ist nur die Hälfte des Speicherproblems
bei der Garbage Collection. Der GC muss auch einen anderen Satz verfolgen: den Satz V (für besucht) aller Zellen, die als zugänglich befunden wurden, um am Ende des Prozesses alle anderen Zellen zurückzugewinnen. Das eine und nicht das andere zu diskutieren ist nur bedingt sinnvoll, da sie ähnliche Kosten verursachen, ähnliche Lösungen verwenden und sogar kombiniert werden können.UV
Das erste, was zu beachten ist, ist, dass alle Trace-GCs demselben abstrakten Modell folgen, das auf einer systematischen Untersuchung des gerichteten Diagramms von Zellen im Speicher basiert, auf die vom Programm aus zugegriffen werden kann, wobei Speicherzellen Scheitelpunkte und Zeiger die gerichteten Kanten sind. Es verwendet dazu die folgenden Mengen:
Die Menge (Visited) der Zellen, auf die der Mutator bereits zugreifen kann , dh das Programm oder der Algorithmus, für den die GC durchgeführt wird. Die Menge V ist in zwei disjunkte Teilmengen unterteilt:
V = U ∪ T ;VVV= U∪ T
die Menge (nicht verfolgt) der besuchten Zellen mit Zeigern, denen noch nicht gefolgt wurde;U
Die Menge (verfolgt) der besuchten Zellen, deren Zeiger verfolgt wurden.T
H
VUUT
UV
UcVUcUT
UUV= TVH- VV
VUUT
Ich überspringe auch Details darüber, was eine Zelle ist, ob sie in einer Größe oder in vielen Größen vorliegt, wie wir darin Hinweise finden, wie sie komprimiert werden können und eine Vielzahl anderer technischer Probleme, die Sie in Büchern und Umfragen zur Müllabfuhr finden können .
U
Wo bekannte Implementierungen sich unterscheiden, liegt die Art und Weise, in der diese Mengen tatsächlich dargestellt werden. Viele Techniken wurden tatsächlich verwendet:
Bitmap: Für eine Map, die ein Bit für jede Speicherzelle enthält, wird ein Teil des Speicherplatzes beibehalten, der über die Adresse der Zelle ermittelt werden kann. Das Bit ist eingeschaltet, wenn sich die entsprechende Zelle in der Menge befindet, die durch die Karte definiert ist. Wenn nur Bitmaps verwendet werden, benötigen Sie nur 2 Bits pro Zelle.
Alternativ können Sie in jeder Zelle Platz für ein spezielles Tag-Bit (oder 2) haben, um es zu markieren.
Log2pp
Sie können ein Prädikat für den Inhalt der Zelle und ihre Zeiger testen.
Sie können die Zelle in einen freien Teil des Speichers verschieben, der für alle Zellen bestimmt ist, die zu dem dargestellten Satz gehören.
VTTU
Sie können diese Techniken sogar für einen einzigen Satz kombinieren.
Wie gesagt, alle oben genannten wurden von einigen implementierten Garbage Collector verwendet, so seltsam einige scheinen mögen. Es hängt alles von den verschiedenen Einschränkungen der Implementierung ab. Und sie können in Bezug auf die Speichernutzung ziemlich billig sein, möglicherweise unterstützt durch die Verarbeitung von Auftragsrichtlinien , die für diesen Zweck frei gewählt werden können, da sie für das Endergebnis keine Rolle spielen.
Was als das seltsamste erscheinen mag, Zellen in ein neues Gebiet zu transferieren, ist tatsächlich sehr verbreitet: Man nennt es Kopiensammlung. Es wird hauptsächlich mit virtuellem Speicher verwendet.
Natürlich gibt es keine Rekursion und der Mutator-Algorithmus-Stack muss nicht verwendet werden.
Ein weiterer wichtiger Punkt ist, dass viele moderne GCs für große virtuelle Speicher implementiert sind . Dann ist es kein Problem, Speicherplatz für die Implementierung und zusätzliche Listen oder Stapel bereitzustellen, da neue Seiten leicht zugewiesen werden können. In großen virtuellen Erinnerungen ist der Feind jedoch nicht der Mangel an Raum, sondern der Mangel an Lokalität . Dann muss die Struktur, die die Mengen darstellt, und ihre Verwendung darauf ausgerichtet sein, die Lokalität der Datenstruktur und der GC-Ausführung zu bewahren . Das Problem ist nicht Raum, sondern Zeit. Bei unzureichenden Implementierungen ist mit größerer Wahrscheinlichkeit eine inakzeptable Verlangsamung zu verzeichnen als bei einem Speicherüberlauf.
Ich habe nicht auf die vielen spezifischen Algorithmen hingewiesen, die sich aus verschiedenen Kombinationen dieser Techniken ergeben, da dies lang genug zu sein scheint.