2009-03-31 6 views
0

Wie schlau ist Garbage Collection, wenn es um verschachtelte Referenzen geht?.Net: Verschachtelte Referenzen

Nehmen Sie diesen Code zum Beispiel:

Public Class SomeClass 
    Private m_SomeOtherClass(Me) 
End Class 

Ich weiß, dass GC Werke betrachten, wie viele Referenzen bleiben, und jedes Objekt ohne Verweis landet abgeladen zu werden. Also, in diesem Fall, wo es eine Referenz gibt, die von einer Mitgliedsvariablen kommt, ist das ein Speicherleck, das darauf wartet zu passieren (es sei denn, Sie implementieren IDisposable, usw.)?

Momentan nehme ich an, dass der GC intelligent genug dafür ist, da er wahrscheinlich überprüfen könnte, ob irgendwelche Referenzen vom Objekt selbst kommen, und sie einfach nicht auf die Referenzzählung zählen. Aber ich dachte, ich würde ein bisschen graben.

Antwort

1

Grundlegende Antwort: Es ist kein Problem.

Ich habe diese Art von Frage schon einmal gehört und sie stammt aus einer Verwirrung mit Referenzzählung, wo Zirkelreferenzierung ein Problem darstellt.

Der .NET-Kollektor zählt keine Referenzen, er scannt und markiert nur referenzierte Objekte. Diese Flags verhindern auch, dass es in eine Schleife geht. Dies ist ein sehr einfacher und praktisch narrensicherer Mechanismus. Das System muss eingehende Referenzen nicht zählen oder verfolgen, so dass für kurzlebige Referenzen kein Overhead vorhanden ist. Aber Sie müssen im Auge behalten, wo Referenzen existieren, ein häufiges Problem sind Objekte, die Ereignisse abonnieren. Das Ereignis behält eine Referenz bei, daher müssen Sie sich abmelden, bevor das abonnierende Objekt wiederhergestellt werden kann. Ein weiterer Vorteil von GC ist, dass die Logik auch umgekehrt funktioniert: Immer wenn Ihr Code Zugriff auf eine Referenz hat, ist diese Referenz garantiert gültig, einfach weil diese Referenz existiert.

Das Referenzzählen erfordert, dass der Compiler Code injiziert, wenn eine Referenz geändert, kopiert oder außerhalb des Gültigkeitsbereichs abgelegt wird, was zu einem konstanten Overhead führt. Wenn der Zählwert auf Null fällt, kann das Objekt sofort zerstört werden. Das System benötigt einen Mechanismus, um Zyklen manuell zu handhaben. Sie können einige Horrorgeschichten finden, indem Sie nach der COM IUnknown-Schnittstelle suchen.

+0

Also beginnt es von einer Reihe von Wurzeln, und geht hinaus, und alles, was nicht referenziert wird, geht. Und es zählt überhaupt keine Referenzen, nehme ich an? –

+0

Richtig, ich werde die Antwort ein wenig erweitern. –

4

Es ist absolut in Ordnung. Der GC arbeitet aus einer Menge von Wurzeln (lokalen und statischen Variablen usw.) und findet alle Referenzen, die er kann. Wenn nichts anderes auf dieses Objekt verweist, das sich gegenseitig referenziert, kann es gesammelt werden.

+0

Mit anderen Worten, das untergeordnete Objekt hat die gleiche Wurzel wie das übergeordnete Objekt und zählt daher nur als Selbstreferenz. –

+0

Nun, könnte es. Das Kind-Objekt * könnte * direkt von anderswo referenziert werden, in diesem Fall würde es das "Eltern" -Objekt am Leben erhalten. Grundsätzlich passiert das Richtige :) –

+0

Toll, danke für die Antwort Jon! –

1

Der GC ist intelligent genug. Es wird sogar beide Objekte gleichzeitig sammeln, wenn sie in der Zeit- und Raumdimension nahe genug zueinander angeordnet sind;)