Der JIT-Compiler und CLR pflegen eine Liste von Anwendungsstammverzeichnissen, die entweder auf Objekte im Heap zeigen oder Null sind. Der GC erstellt einen Graphen aus diesen Wurzeln und markiert alle Objekte in dem Heap, die in diesem Graphen referenziert sind - der Rest ist Müll.
Meine Frage ist: Wie werden die Wurzeln null?
Der offensichtliche Fall ist, wenn eine Variable im Code explizit auf Null gesetzt wird. Aber was, wenn nicht? Wie weiß der jit/clr, wann man eine Wurzel auf null setzen kann?GC und Anwendungswurzeln
Antwort
Mein Verständnis ist, dass die Zeiger in den Anwendungswurzeln nicht auf Null gesetzt sind. Dies ist ein wenig kontraintuitiv (IMHO), weil es den Anschein hat, als ob der schnellste Weg, ein Objekt zu entfernen, darin besteht, einfach den Zeiger darauf loszuwerden, ähnlich wie das FAT-Dateisystem einfach einen FAT-Eintrag markiert, um eine Datei zu löschen , ohne diesem "Zeiger" tatsächlich auf die Bytes auf der Platte zu folgen und sie auf Null zu setzen. Ich habe eine Interviewfrage verpasst, die das berührt hat, also habe ich ein bisschen darüber gelesen, obwohl es genau null Anwendbarkeit für alles hat, worüber wir uns täglich Sorgen machen.
In jedem Fall ... Jeffrey Richter schrieb vor zwölf Jahren einen MSDN-Artikel, der dies ansprach. Aus seinem Artikel habe ich Folgendes gelernt.
Wenn der GC ausgeführt wird, wird davon ausgegangen, dass alle Anwendungs-Roots auf nicht erreichbare Objekte zeigen. Es geht die Wurzeln, folgt ihnen zu Objekten auf dem Haufen (oder entdeckt, dass sie auf nichts Gültiges zeigen). Dies geschieht rekursiv, indem ein neuer Graph von erreichbaren Objekten erstellt wird. Dann geht es den Haufen, verschiebt gültige Objekte und repariert ihre Zeiger - der Effekt davon ist, den freien Speicher an der Spitze des Heaps zu konsolidieren. An einem bestimmten Punkt in diesem Prozess wird der Graph der erreichbaren Objekte zurück in die Anwendungs-Roots kopiert und ersetzt diese. Ich bin mir nicht sicher, ob dies vor oder nach der Verdichtung des Heaps passiert.
Die Ausgaben Dezember '12 und Januar '13 des MSDN Magazine enthalten auch einen Artikel über C# Speicherverwaltung. Ich habe es nicht gelesen, sondern geplant - es könnte alles klären.
Noch ein Fall: Wenn Sie den Bereich verlassen, werden lokale Variablen, die im Codeblock definiert sind, unerreichbar, weil Sie eine lose Funktion stackframe und damit Verweise auf diese Objekte haben. –