[Je voulais juste ajouter davantage sur le processus de finalisation interne]
Ainsi, vous créez un objet et lorsque l'objet est collecté, la Finalize
méthode de l'objet doit être appelée. Mais il y a plus à finaliser que cette hypothèse très simple.
CONCEPTS COURTS ::
Les objets n'implémentant PAS de Finalize
méthodes, la mémoire est récupérée immédiatement, sauf si bien sûr, ils ne sont plus accessibles par le
code de l'application
Les objets implémentant Finalize
Méthode, le concept / Mise en œuvre Application Roots
, Finalization Queue
, Freacheable Queue
vient avant de pouvoir être remis en état.
Tout objet est considéré comme une poubelle s'il n'est PAS accessible par le code d'application
Supposons que: les classes / objets A, B, D, G, H n'implémentent PAS la Finalize
méthode et C, E, F, I, J implémentent la Finalize
méthode.
Lorsqu'une application crée un nouvel objet, l'opérateur new alloue la mémoire à partir du tas. Si le type de l'objet contient une Finalize
méthode, un pointeur vers l'objet est placé dans la file d'attente de finalisation .
par conséquent, des pointeurs vers les objets C, E, F, I, J sont ajoutés à la file d'attente de finalisation.
La file d'attente de finalisation est une structure de données interne contrôlée par le garbage collector. Chaque entrée de la file d'attente pointe vers un objet dont la Finalize
méthode doit être appelée avant que la mémoire de l'objet puisse être récupérée. La figure ci-dessous montre un tas contenant plusieurs objets. Certains de ces objets sont accessibles depuis les racines de l' application, et certains ne le sont pas. Lorsque les objets C, E, F, I et J ont été créés, le framework .Net détecte que ces objets ont des Finalize
méthodes et des pointeurs vers ces objets sont ajoutés à la file d'attente de finalisation .
Lorsqu'un GC se produit (1ère collecte), les objets B, E, G, H, I et J sont considérés comme des déchets. Parce que A, C, D, F sont toujours accessibles par le code d'application représenté par les flèches de la boîte jaune ci-dessus.
Le garbage collector analyse la file d'attente de finalisation à la recherche de pointeurs vers ces objets. Lorsqu'un pointeur est trouvé, le pointeur est retiré de la file d'attente de finalisation et ajouté à la file d'attente accessible ("F-accessible").
La file d'attente accessible est une autre structure de données interne contrôlée par le garbage collector. Chaque pointeur de la file d'attente accessible identifie un objet prêt à recevoir l' Finalize
appel de sa méthode.
Après la collection (1ère collection), le tas géré ressemble à la figure ci-dessous. Explication donnée ci-dessous:
1.) La mémoire occupée par les objets B, G et H a été récupérée immédiatement parce que ces objets n'avaient pas de méthode de finalisation à appeler .
2.) Cependant, la mémoire occupée par les objets E, I et J n'a pas pu être récupérée car leur Finalize
méthode n'a pas encore été appelée.
L'appel de la méthode Finalize se fait par une file d'attente accessible.
3.) A, C, D, F sont toujours accessibles par le code d'application représenté par les flèches de la boîte jaune ci-dessus, donc ils ne seront PAS collectés dans tous les cas
Il existe un thread d'exécution spécial dédié à l'appel des méthodes Finalize. Lorsque la file d'attente accessible est vide (ce qui est généralement le cas), ce thread se met en veille. Mais lorsque des entrées apparaissent, ce thread se réveille, supprime chaque entrée de la file d'attente et appelle la méthode Finalize de chaque objet. Le garbage collector compacte la mémoire récupérable et le thread d'exécution spécial vide la file d'attente accessible en exécutant la Finalize
méthode de chaque objet . Voici donc enfin quand votre méthode Finalize est exécutée
La prochaine fois que le garbage collector est appelé (2nd Collection), il voit que les objets finalisés sont vraiment des déchets, car les racines de l'application ne pointent pas vers elle et la file d'attente accessible ne pointe plus vers elle (c'est VIDE aussi), donc le la mémoire pour les objets (E, I, J) est simplement récupérée à partir de Heap.Voir la figure ci-dessous et la comparer avec la figure juste au-dessus
La chose importante à comprendre ici est que deux GC sont nécessaires pour récupérer la mémoire utilisée par les objets qui nécessitent une finalisation . En réalité, plus de deux collections peuvent même être nécessaires car ces objets peuvent être promus à une génération plus ancienne
REMARQUE: La file d'attente accessible est considérée comme une racine, tout comme les variables globales et statiques sont des racines. Par conséquent, si un objet se trouve dans la file d'attente accessible, l'objet est accessible et n'est pas une poubelle.
Pour terminer, rappelez-vous que le débogage de l'application est une chose, le garbage collection en est une autre et fonctionne différemment. Jusqu'à présent, vous ne pouvez pas ressentir le ramassage des ordures simplement en déboguant les applications, plus si vous souhaitez étudier la mémoire, commencez ici.