2009-11-01 2 views
1

Il s'agit d'une question liée au CLR .net..net Question connexe au CLR

J'ai 3 objets objet A, B, C

A Refres B et B fait référence c

Que deviennent ces objets dans le tas si je tue l'objet "A" explicitly.Which sera garbage collect? (objet A ou B ou c ou tous?)

Quelqu'un peut-il expliquer le processus de récupération de place dans ce scénario en détail.

Merci à l'avance SNA

+0

comment tuez-vous A? –

Répondre

9

Première - vous ne pouvez pas "tuer l'objet "A" explicitement"; vous pouvez effacer la référence, mais cela définit simplement une variable locale à null et n'a rien à voir avec l'objet réel sur le tas géré. Vous pouvez Dispose() il, mais c'est rien à voir avec GC.

Tout dépend; peut autre chose voir B/C? Sinon, ils sont éligibles pour la collecte. Mais GC est non-déterministe; ça n'arrive que quand ça le veut. À certains indéterminé temps, GC entrera, détecter que ces objets sont inaccessibles, et les supprimer. Dans le processus, il vérifiera ceux qui ont des finaliseurs (qui sont encore en suspens), et exécutera les finaliseurs (dans un processus en deux étapes).

Une chose que les gens oublient souvent en termes d'accessibilité sont les événements; si B/C s'abonner à des événements sur un objet de longue durée, alors B/C sont accessibles (par l'éditeur d'événement).


Pour clarifier; GC fonctionne en créant un arbre à partir des objets racine (threads, etc). Il marche chaque référence, signalant tous les objets qui peuvent être atteints. Tout ce qui n'est pas marqué à la fin est éligible pour la collecte. Cela évite le problème COM/COM + d'obtenir des fuites de mémoire dues à des îlots de données déconnectés, où X => Y et Y => X (donc X et Y ont tous deux des ref-positifs, donc aucun n'est effacé).

1

Le premier malentendu pourrait être que vous ne pouvez pas tuer explicitement un objet géré.

Vous pouvez libérer de la mémoire non gérée que vous avez vous-même allouée, mais qui n'est pas gérée et qui n'est pas soumise à la récupération de place. Lorsque vous définissez la référence à A sur null ou qu'elle est hors de portée, il n'y aura aucune référence à B & C et la prochaine collection GC s'en chargera.

1

Dans .NET, il n'existe aucun moyen de tuer/supprimer un objet. Tout ce que vous pouvez faire explicitement est de disse un objet. Ce rien de plus qu'un simple appel à Dispose() sur votre objet. Cela vous permettra de nettoyer votre objet avant qu'il ne soit collecté par le garbage collector plus tard (que vous ne pouvez pas vraiment infulencer). Voir IDisposable sur plus de détails. La deuxième option pour avoir une chance de nettoyer votre objet avant qu'il ne soit collecté par le GC est d'implémenter un finalizer. Contrairement au Dispose(), il sera appelé automatiquement par le GC.Encore une fois, les deux sont juste moyen de nettoyer les ressources avant qu'un objet puisse cesser d'exister. Donc pour répondre à votre question si votre objet A est "tué" ce qui arrive seulement quand il n'est plus référencé par aucun autre objet, B et C seront "tués" à SI ils ne sont référencés que par A. Habituellement, vous faites pas d'influence sur quand cela se produit réellement. Tout ce que vous pouvez faire est de mettre en œuvre le finaliseur pour être averti quand cela arrive. Le GC est un service d'arrière-plan qui s'exécute sur un thread distinct qui suit une logique complexe lorsqu'il s'agit de supprimer réellement des objets.

Si vous voulez comprendre le fonctionnement du GC, je suggérerais twoarticles. Bien qu'ils soient un peu vieux, ils s'appliquent encore pleinement.