2016-10-01 3 views
-2

Ich bin mit einer seltsamen Situation konfrontiert.Hinzugefügt Objekt auf der Liste <T> kann von GC gesammelt werden? (Xamarin Formen)

Wie ich weiß, wenn Objekt zu Array hinzugefügt wird (wie eine Liste), wird die Anzahl der Referenzen erhöht, so dass es nicht aus GC erfasst werden kann.

Also wenn ich IList Variable (= neue Liste der natürlich) in Singletone und es Objekte hat, können die Objekte nicht von GC gesammelt werden.

Ist das korrekt?

+2

Klingt ungefähr richtig. Da gibt es einen Verweis auf das Objekt. –

+0

Ich möchte nur wissen, ob es richtig ist, dann muss ich prüfen, ob es einen anderen Fehler gibt. Vielen Dank! –

+0

Bitte lesen Sie [fragen]. _ "Wird dieser Code, den ich nicht zeige und den ich nicht annähernd genug erzähle, um das ganze Bild zu malen, funktionieren?" _ Ist nicht zu verantworten. – CodeCaster

Antwort

2

Referenzzählung ist nicht die Art, darüber nachzudenken, der GC funktioniert nicht auf diese Weise; es ist schlau genug, um zu wissen, dass es zwei Objekte sammeln kann, die aufeinander verweisen, aber keine anderen Live-Referenzen haben, die auf sie zeigen.

public void Blah() 
{ 
    var foo1 = new Foo(); 
    var foo2 = new Foo(); 
    foo1.OtherFoo = foo2; 
    foo2.OtherFoo = foo1; 
} //at this point, both foo1 and foo2 are eligible for collection 

Wenn nur überprüft wird, ob die Referenzzählung eines Objekts gleich Null ist, würde es in diesem einfachen Fall nicht abgeschnitten. Stellen Sie sich ein Objekt als für die Sammlung geeignet vor, wenn keine (oder erreichbaren) Referenzen darauf verweisen.

In Bezug auf Ihre Frage, solange Ihre List erreichbar ist, sind die darin enthaltenen Objekte erreichbar und daher werden sie nicht gesammelt. jedoch bemerkt, auf dem, was ich vorher erklärt, dass, wenn Ihre Liste nicht erreichbar ist, dann ist die Liste selbst, und alle darin enthaltenen Objekte, die nicht erreichbar durch eine andere Referenz, sind wahlberechtigte abhol:

public void Blah() 
{ 
    var list = new List<Foo>(); 
    var foo1 = new Foo(); 
    var foo2 = new Foo(); 
    list.AddRange(new[] { foo1, foo2 }); 
} //at this point, foo1, foo2 and list are eligible for collection 

Die Liste selbst kann auch dann gesammelt werden, wenn Verweise auf darin enthaltene Objekte existieren! Betrachten wir zum Beispiel den folgenden Code:

static void Main(string[] args) 
{ 
    var o = new object(); 
    Foo(o); 
    //At this point the list created in Foo(o) is eligible for collection, even if 
    //o is not! Collecting the list does not mean that its contents are collected too. 
    Console.WriteLine(o.ToString()); 
} 

private static void Foo(object o) 
{ 
    var list = new MyList<object>(); 
    list.Add(o); 
} //at this point list is eligible for collection! 

Der Punkt ist, dass, obwohl eine Liste einen Verweis auf die Objekte halten es enthält in der Regel diese Objekte keinen Hinweis auf den Behälter halten.

Eine andere Subtilität; In meinen vorherigen Beispielen können Sie die Berechtigung für die Sammlung mit dem Bereich angeben. Das wäre ein falscher Glaube. Die Laufzeitumgebung ist intelligent genug, um Objekte zu erfassen, die sich noch im Gültigkeitsbereich befinden, wenn absolut sicher ist, dass niemand auf sie schreibt oder von ihnen liest. Um formal korrekt zu sein, sollten die vorherigen Beispiele umgeschrieben werden in:

public void Blah() 
{ 
    var list = new List<Foo>(); 
    var foo1 = new Foo(); 
    var foo2 = new Foo(); 
    list.AddRange(new[] { foo1, foo2 }); 
    //at this point, foo1, foo2 and list are eligible for collection 
} 
Verwandte Themen