2010-02-26 8 views
18

GC est pour les objets gérés et Finalize est pour les objets non gérés c'est ce que j'ai lu. Dispose est implicite et Finalize is Explicit est ce que j'ai lu. Quelqu'un peut-il me donner un exemple d'un module dans lequel les trois choses ont été utilisées pour différentes raisons?Quelle est la relation entre GC, Finalize() et Dispose?

+4

Vous pouvez aussi bien ajouter 'Using 'dans le mixage pendant que vous y êtes. – RedFilter

Répondre

25

GC est la collecte des ordures. C'est la gestion automatique de la mémoire, qui gère le nettoyage des objets alloués sur le tas géré. Le GC .NET utilise un algorithme de marquage et de balayage. Quand un garbage collection se produit, il considère fondamentalement que tous les objets dans la partie du tas soient nettoyés comme récupérables. Ensuite, il passe par un processus de marquage où il recherche les racines. C'est à dire. il identifie les objets qui sont toujours utilisés par l'application. Après avoir fait cela, les objets restants sont admissibles au nettoyage. Le tas peut être compacté dans le cadre du nettoyage.

Les méthodes Dispose et Finalizer offrent toutes deux une option pour le nettoyage des ressources, à savoir et non géré par GC. Par exemple. cela pourrait être des poignées natives et similaires. Ils n'ont rien à voir avec la récupération de la mémoire sur le tas géré. Dispose doit être appelé explicitement sur un type implémentant IDisposable. Il peut être appelé par la méthode Dispose() elle-même ou via la construction using. Le GC n'appelle pas Dispose automatiquement. Par contre, un finaliseur ou un destructeur (comme l'appellent les spécifications de langage) sera automatiquement appelé et après que l'objet ait été éligible au nettoyage. Les méthodes de finalisation sont exécutées séquentiellement sur un thread dédié.

Dispose() permet un nettoyage déterministe des ressources tandis qu'un finaliseur peut agir comme un filet de sécurité au cas où l'utilisateur n'appelle pas Dispose().

Si un type implémente un finaliseur, le nettoyage des instances est retardé car le finaliseur doit être appelé avant le nettoyage. C'est à dire. il faudra une collecte supplémentaire pour récupérer la mémoire pour les instances du type. Si le type implémente IDisposable, la méthode Dispose peut être appelée, puis l'instance peut se retirer de la finalisation. Cela permettra à l'objet d'être nettoyé comme s'il n'avait pas de finaliseur.

Si vous voulez creuser dans ce domaine, je recommande CLR via C# by Jeffrey Richter. C'est un livre génial qui couvre tous les détails sanglants (j'ai laissé de côté un certain nombre de détails). La nouvelle 3ème édition vient de sortir.

+1

+1, mais vous pouvez ajouter que vous pouvez supprimer le finaliseur avec GC.SupressFinalize, ce que vous voulez faire si vous disposez explicitement de l'instance. –

+0

Si Finalize est automatiquement appelé quand un objet est éligible au nettoyage alors pourquoi C ne le fait-il pas? Si c'est un processus automatique? – TeaLeave

+0

Il n'est pas appelé immédiatement. Il est prévu d'être appelé. Cela peut prendre un certain temps avant qu'il ne soit exécuté. –

7

Vous voudrez peut-être lire ce que je considère être l'article final sur IDisposable, finaliseurs et éboueurs, CLR Inside Out: Digging into IDisposable de Shawn Farkas.

Cet article laisse très peu de doute sur le sujet.

+2

Salut Mark, la différence entre Dipose() et deux autres est ce que j'ai compris, mais où j'ai du mal à comprendre la différence entre Finalize() et Garbage Collector(). parce que je suis tombé sur de nombreux articles où je dis que l'auteur utilise finalement Finalize() pour effacer les objets. Alors quelle est la différence entre garder Finalize() dans la définition de la classe et ne pas en conserver une car même si je ne conserve pas Finalize() dans ma définition de classe, GC finit par appeler Finalize() pour effacer l'objet inutilisé. – TeaLeave

+0

Maintenant, quelque part, j'ai lu que les objets avec Finalize() seront placés dans "Finalization Queue" et que lorsque l'objet n'est plus nécessaire, la mémoire est récupérée GC. – TeaLeave

+0

Les choses semblent si entremêlées parce que GC est Usign Finalize() et Finalize utilise GC :). Je suis confus ......... – TeaLeave

8

Un des avantages de .NET est le garbage collector. Dans de nombreuses langues, chaque morceau de mémoire doit être géré par le développeur - toute mémoire allouée devrait éventuellement être libérée. En .NET (C#), le garbage collector (GC) prendra soin du processus de libération de la mémoire pour vous. Il suit l'utilisation de vos objets, et après qu'ils deviennent "non racinés" (ie: il n'y a aucune référence dans votre application à cet objet, directement ou indirectement), la mémoire de l'objet est automatiquement nettoyée.

Disposer, ou plus particulièrement, IDisposable et le motif Dispose, est utilisé pour gérer les ressources séparément du CPG. Certaines ressources doivent être nettoyées explicitement , pour diverses raisons. Cela inclut l'utilisation d'une API "native" (où.NET ne connaît pas la mémoire allouée), en utilisant une ressource qui enveloppe les poignées natives, etc. Afin de gérer cela proprement, vous implémentez IDisposable et le motif Dispose.

La finalisation se produit sur les objets lorsqu'ils sont sur le point d'être collectés par le garbage collector. Cela fournit un "filet de sécurité" où par un objet qui aurait dû être éliminé peut encore être nettoyé, si un peu plus tard que l'idéal. En implémentant un finaliseur, vous pouvez garantir que les ressources non managées sont toujours libérées. Le problème avec la plupart des exemples est qu'il existe plusieurs raisons d'utiliser IDisposable, et l'implémentation correcte diffère selon la raison pour laquelle vous l'utilisez. Par exemple, si vous encapsulez une ressource native directement, vous devez implémenter un finaliseur, mais si vous encapsulez un autre type IDisposable, un finaliseur n'est pas nécessaire, même si vous devez toujours implémenter IDisposable. Afin de résoudre ce problème, j'ai écrit à propos de IDisposable and finalization in depth on my blog, décrivant les multiples raisons pour lesquelles vous utiliseriez IDisposable, et différents modèles pour des raisons différentes.

Questions connexes