ist es legal, einen verwurzelter Verweis auf ‚diesem‘ in einer .net destructor neu zu erstellen?
-
03-07-2019 - |
Frage
Ist es legal, die folgend in .net?
zu schreiben public class A
{
public int i = 0;
~A()
{
Aref = this;
}
}
public static A Aref;
static void Main(string[] args)
{
Aref = new A();
int gen = GC.GetGeneration(Aref);
Aref = null;
GC.Collect(gen, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
Console.WriteLine(Aref.i);
Console.ReadLine();
}
Es funktioniert und schreibt ‚0‘ auf die Konsole als erwartet, aber ich frage mich, wenn sichergestellt ist, immer zu arbeiten.
Hat jemand wissen, was hinter den Kulissen passiert?
Lösung
Es ist Auferstehung genannt, und es ist legal. Google für „.net Objekt Auferstehung“ (und Begriffe wie es), und Sie werden solche Sachen finden:
Auferstehung und .NET Garbage Collector
Auferstehung Objekt
So stellen Sie sicher, dass diese Zombie-Objekte kommen nicht zurück und versuchen Sie Ihr Gehirn oder etwas zu essen. Wie alle Nekromantie, ist dies gefährlich Sachen. (Vor allem, weil die Finalizers höher in der Klassenhierarchie kann einige wesentlichen Ressourcen freigegeben hat. Beachten Sie auch, dass der Finalizerthread nicht ein zweites Mal ausgeführt werden, wenn das Objekt „unreferenced“ wird, es sei denn, Sie GC.ReRegisterForFinalize
nennen.)
Andere Tipps
Es funktioniert, weil die erste Garbage Collection nicht die Instanz sammelt. Es nur plant die Instanz seinen Finalizerthread Lauf zu haben. Die Finalizerthread erstellt dann eine neue Wurzel zum Beispiel so, wenn die nächste Sammlung der Instanz geschieht tatsächlich verwurzelt und somit nicht zur Sammlung.
Sie sollten mit diesem harten sehr vorsichtig sein. Wenn der Finalizer sicherstellen verwendet wird ein Objekt angeordnet ist, verletzt dies tatsächlich das Protokoll, da das Einweg-Muster sagt, dass eine angeordnete Instanz sollte eine ObjectDisposedException werfen, wenn sie, nachdem sie entsorgt verwendet wird.
Der Garbage-Collector-Objekte in drei Gruppen unterteilt:
- Diejenigen, die noch am Leben sind, weil schließlich eine verwurzelte Referenz überprüfen existiert außerhalb der Finalisierungsschlange;
- solche, die müssen gelöscht werden, weil kein verwurzelten Referenz überall vorhanden;.
- Diejenigen, die fertig gestellt werden müssen, weil eine verwurzelte Referenz in der Finalisierungsschlange existiert, aber nirgendwo sonst