Manuellement détruire les objets C#
Je suis assez nouveau à l'apprentissage du C# (à partir de Java & C++ arrière-plan) et j'ai une question à propos du manuel d'élimination des déchets: il est même possible de manuellement détruire un objet en C#? Je sais que sur le IDisposable
interface, mais supposons que je fais face à une classe, que je n'ai pas écrit et il n'a pas la mettre en œuvre? Il n'y aurait pas un .Dispose()
méthode, de sorte que et using { }
est sorti, et .Finalize
est toujours soit protected
ou private
ce n'est donc pas une option non plus.
(Je suis juste essayer d'apprendre ce qui est possible en C# dans ce cas. Je suppose que si tout le reste échoue, je pouvais hériter l'hypothétique ImNotDisposable
classe de façon à ce qu'il ne mettre en œuvre IDisposable.)
- Vous devriez peut-être clarifier la question: voulez-vous de libérer un objet entièrement, ou tout simplement de la force de son destructeur de la méthode execute et nettoyer l'objet de ressources (seulement)?
- Je présume que l'un implique l'autre, mais ce que j'avais en tête était d'une certaine façon à "déclencher" le ~ClassName() méthode d'un objet.
- Donc, pour résumer, GC a la collect() méthode qui est à peu près tout-ou-rien, et pas n'importe comment pour cible un objet spécifique. Gotcha. 🙂
Vous devez vous connecter pour publier un commentaire.
Vous n'avez pas manuellement les détruire .Net des objets. C'est ce qui est gestion de l'environnement est tout au sujet.
En fait, si l'objet est réellement accessible, ce qui signifie que vous avez une référence, vous pouvez utiliser pour dire à la GC de l'objet que vous voulez détruire, la collecte de l'objet sera impossible. Le GC jamais recueillir tout objet qui est toujours accessible.
Ce que vous pouvez faire est d'appeler
GC.Collect()
pour forcer une collection générale. Cependant, cette presque jamais une bonne idée.Au lieu de cela, il est probablement préférable de simplement semblant tout objet qui n'est pas l'utilisation des ressources non managées et n'est pas accessible par n'importe quel autre objet dans votre programme est immédiatement détruit. Je sais que cela ne se produise pas, mais à ce point l'objet est seulement un bloc de la mémoire comme les autres; vous ne pouvez pas la récupérer et elle finira par être collectées, de sorte qu'il peut tout aussi bien être morte pour vous.
Une dernière remarque sur
IDisposable
. Vous devez utiliser uniquement pour les types qui enveloppent non géré ressources: des choses comme des sockets, des connexions de base de données, les objets gdi, etc, et, à l'occasion de l'événement/délégué abonnement.Si l'objet n'est pas accessible, alors vous pouvez appeler
GC.Collect()
et l'objet sera détruit. Le concept deIDisposable
n'a rien à voir avec le CLR et surtout pour le code utilisateur à mettre en œuvre pour effectuer supplémentaires l'élimination de la logique. Appelant dispose() sur un objet ne sera pas l'objet lui-même de la mémoire, mais il peut très bien éliminer toutes les ressources que cette des références d'objet.Je dois ajouter que, si ce que j'ai dit est une façon d'atteindre cet objectif, dans 99,9999% des applications que vous ne devriez jamais appel
GC.Collect()
parce qu'il va souvent dégrader les performances de votre application au lieu de l'améliorer.GC.Collect()
n'est pas quelque chose que vous devriez faire, sauf si c'est pour un très une bonne raison.GC.Collect()
espacés de quelques minutes d'intervalle dans le temps même de nuire à la performance?Bien que vous pouvez déclencher la collecte des ordures (vous avez besoin de déclencher GC pour toutes les générations, parce que vous ne pouvez pas être sûr de la génération de l'objet finalisable est dans) vous ne pouvez pas nécessairement forcer la finalisation d'un objet particulier. Vous ne pouvez dépendent des hypothèses sur la façon dont le garbage collector œuvres.
Furtnermore, depuis la finalisation qui se passe sur son propre thread, vous devez appeler WaitForPendingFinalizers après le déclenchement de la collecte des ordures.
Comme il a été mentionné par d'autres, cela peut affecter les performances de votre application car inutilement invoquant le GC peut promouvoir autrement courte durée de vie des objets dans les générations subséquentes qui sont plus coûteux à collecter et sont collectées moins fréquemment.
De manière générale, une classe qui implémente un finaliseur (destructeur) et de ne pas mettre en œuvre IDisposable, c'est mal vu. Et tout ce qui implémente IDisposable devrait être de l'appeler finaliseur de la logique et de la supressing lui-même à partir de finalisation à la collecte des ordures.
Jeff Richter a récemment posté une jolie petite astuce pour recevoir une notification lors de la collecte des ordures se produit.
Un autre excellent article sur Garbage Collector notions de base et les Performances des Astuces par Rico Mariani (MSFT)
Non, on ne peut pas détruire un objet spécifique.
Il est possible d'invoquer le garbage collector, qui va chercher les objets à détruire, mais elle n'est presque jamais une bonne idée.
Vous peut vigueur le garbage collector de courir après la variable que vous voulez détruire est hors de portée, mais normalement, vous ne voulez pas le faire, que le garbage collector est plus efficace si la gauche pour faire son propre travail.
De forcer le garbage collection qui peut être fait avec GC.Recueillir, mais ne pas le faire. Dans mes 10 ans .NET développeur, je n'ai jamais eu besoin.
Vous ne peut pas manuellement détruire un objet "comme le C++ supprimer", tout ce que vous pouvez faire est de simplement fermer toutes les ressources exclusives l'objet a acquis et null toutes les références à cet objet, de sorte que le GC peut recueillir, aussi, ne pas appeler GC.Collect() par vous-même, le GC processus est coûteux, car il a de suspendre tous les autres threads en toute sécurité de collecter les objets de la mémoire, donc il suffit de faire confiance à la GC, et il sera le coup d'envoi en cas de besoin.
Il n'est pas possible de détruire un objet dans une manière déterministe. Le CLR détermine le moment où le pavillon objet est récupéré. Cela signifie que même si vous pouvez marquer un objet pour la remise en état et de s'assurer que gérées et non gérées les ressources sont dégagés pour l'élimination (par la mise en œuvre de la IDisposable modèle), le temps réel de la mémoire est libérée est à la CLR. C'est à partir de C++ où l'on pouvait supprimer quelque chose, et il serait libéré ensuite.
Dire que vous avez une classe matrice et vous avez créé deux objets matrix
aMatrix
etbMatrix
. En C#, vous pouvez manuellement détruire (finaliser) un objet de la sorte:Le garbage collector remarquerez que votre
aMatrix
est nulle, et les détruisent (finaliser) il. Si oui ou non c'est une bonne idée, c'est une autre histoire.