Considérez ces deux classes:
public class A
{
B b;
public A(B b) { this.b = b; }
}
public class B
{
A a;
public B() { this.a = new A(this); }
}
Si j'ai des classes conçues comme ci-dessus, les objets de ces classes seraient-ils collectés par Garbage Collector (GC)?
Supposons que je fasse ceci:
void f()
{
B b = new B();
}
Dans cette méthode, je crée une instance de B
appelée b
, et lorsque la méthode revient, b
sort du domaine d'application et le GC doit être en mesure de la collecter, mais s'il devait le collecter, il devrait d'abord collecter a
qui est le membre de B
, et pour collecter a
, il doit collecter b
premier qui est le membre de A
. Cela devient circulaire. Ma question est donc: une telle référence circulaire va-t-elle empêcher le GC de collecter les objets?
WeakReference
? Quel est son objectif?Le garbage collector .Net peut absolument gérer les références circulaires. La très vue de haut niveau du fonctionnement du ramasse-miettes est ...
Cela permet de recueillir très bien les références circulaires. Tant qu'aucune d'entre elles n'est accessible à partir d'un objet connu pour être irrécouvrable, la référence circulaire est essentiellement hors de propos.
Remarque: je me rends compte que j'ai omis de nombreux détails amusants afin de garder cette réponse simple et directe
Non, ce ne sera pas un problème car le GC peut gérer les références circulaires
MSDN dit
Si un groupe d'objets contient des références les uns aux autres, mais qu'aucun de ces objets n'est référencé directement ou indirectement à partir de la pile ou de variables partagées, la récupération de place récupère automatiquement la mémoire.
Plusieurs réponses ont déjà expliqué que les références circulaires ne sont pas un problème.
Quant aux références faibles - la raison de les utiliser est la mise en cache.
Lorsque GC parcourt les arbres de dépendance des objets, il ignore les références faibles. En d'autres termes, si la seule référence à un objet est faible, ce sera le garbage collection, mais s'il n'y a pas eu de garbage collection entre la création de la référence et votre tentative d'utilisation, vous pouvez toujours accéder à l'objet.
Non, cette référence circulaire n'affectera pas le garbage collector, et elle sera parfaitement capable de collecter l'instance de B.
Le garbage collector sait que personne ne peut référencer l'instance de B après être hors de portée, et par conséquent, personne ne peut utiliser l'instance de B pour référencer indirectement A.