Ich habe ein Test, gebe ich zu erwarten, aber das Verhalten des Garbage Collector ist nicht, wie ich vermutet:Garbage Collection sollte Objekt entfernt haben, aber WeakReference.IsAlive noch gibt true zurück
[Test]
public void WeakReferenceTest2()
{
var obj = new object();
var wRef = new WeakReference(obj);
wRef.IsAlive.Should().BeTrue(); //passes
GC.Collect();
wRef.IsAlive.Should().BeTrue(); //passes
obj = null;
GC.Collect();
wRef.IsAlive.Should().BeFalse(); //fails
}
In diesem Beispiel wird die obj
Objekt sollte GC'd sein und daher würde ich erwarten, dass die WeakReference.IsAlive
Eigenschaft false
zurückgibt.
Es scheint, dass, weil die obj
Variable im gleichen Umfang wie die GC.Collect
deklariert wurde, wird es nicht gesammelt. Wenn ich die Obj-Deklaration und Initialisierung außerhalb der Methode verschiebe, wird der Test bestanden.
Hat jemand eine technische Referenzdokumentation oder Erklärung für dieses Verhalten?
Haben Sie überprüft, wie der IL-Code aussieht? Verhält es sich auch für Release- und Debug-Builds auf die gleiche Weise? –
Meine erste Vermutung ist, dass Compiler/Laufzeit/Prozessor-Optimierungen Sie beißen. Sie stellen fest, dass Sie nie "obj" lesen, so dass es erlaubt ist, die Operationen zwischen den anderen Methodenaufrufen neu zu ordnen. Versuchen Sie etwas wie 'Console.WriteLine (obj == null)' hinzuzufügen, nur um den Compiler daran zu hindern. – Servy
Dieses Beispiel funktioniert auf meinem Computer einwandfrei. Ich benutze 'Console.WriteLine', um den' IsAlive' Parameter zu protokollieren, anstelle von 'Should()' – JaredPar