Destructeurs et méthodes Finalize
Pour la plupart des objets créés par votre application, vous pouvez compter sur le garbage collector du .NET Framework pour effectuer implicitement toutes les tâches nécessaires de gestion de la mémoire. Lorsque vous créez des objets qui encapsulent des ressources non managées, vous devez toutefois libérer explicitement les ressources non managées lorsque vous avez terminé de les utiliser dans votre application. Le type le plus courant de ressource non managée est un objet qui encapsule une ressource du système d'exploitation, telle qu'un fichier, une fenêtre ou une connexion réseau. Bien que le garbage collector puisse assurer le suivi de la durée de vie d'un objet qui encapsule une ressource non managée, il ne possède pas d'informations spécifiques sur le nettoyage de la ressource. Pour ces types d'objets, le .NET Framework fournit la méthode Object.Finalize, qui permet à un objet de nettoyer correctement ses ressources non managées lorsque le garbage collector récupère la mémoire utilisée par l'objet. Par défaut, la méthode Finalize n'effectue aucune opération. Pour que le garbage collector effectue des opérations de nettoyage sur votre objet avant qu'il ne récupère la mémoire de l'objet, vous devez substituer la méthode Finalize dans votre classe.
Notes
Pour implémenter la méthode Finalize en C#, vous devez utiliser une syntaxe de destructeur. Dans la version 2.0 du .NET Framework, Visual C++ utilise sa propre syntaxe pour implémenter la méthode Finalize, comme décrit dans Destructors and Finalizers in Visual C++. Dans les versions 1.0 et 1.1 du .NET Framework, Visual C++ utilisait la syntaxe du destructeur pour la méthode Finalize, comme le fait C#.
Le garbage collector assure le suivi des objets qui possèdent des méthodes Finalize, grâce à une structure interne appelée file d'attente de finalisation. Chaque fois que votre application crée un objet qui possède une méthode Finalize, le garbage collector place une entrée dans la file d'attente de finalisation qui pointe vers cet objet. La file d'attente de finalisation contient des entrées pour tous les objets figurant dans le tas managé et dont le code de finalisation doit être appelé avant que le garbage collector ne puisse récupérer leur mémoire.
Notes
L'exemple de code indiqué pour la méthode System.GC.KeepAlive(System.Object) affiche la façon dont un recyclage agressif peut entraîner l'exécution d'un finaliseur pendant qu'un membre de l'objet demandé se trouve en cours d'exécution et la façon d'utiliser la méthode KeepAlive pour éviter ce problème.
Une méthode Finalize ne doit pas lever d'exceptions, parce qu'elles ne peuvent pas être gérées par l'application et peuvent provoquer l'arrêt de cette dernière.
L'implémentation des destructeurs ou des méthodes Finalize peut avoir un impact négatif sur les performances et il est préférable d'éviter de les utiliser inutilement. La récupération de la mémoire utilisée par des objets possédant des méthodes Finalize implique au moins deux garbage collections. Lorsque le garbage collector effectue un garbage collection, il récupère de la mémoire pour des objets inaccessibles ne possédant pas de finaliseurs. À ce stade, il ne peut pas collecter les objets inaccessibles qui possèdent des finaliseurs. Il supprime à la place les entrées de ces objets dans la file d'attente de finalisation et les place dans une liste d'objets marqués comme étant prêts pour la finalisation. Les entrées figurant dans cette liste pointent vers les objets du tas managé dont le code de finalisation est prêt à être appelé. Le garbage collector appelle les méthodes Finalize des objets figurant dans cette liste, puis supprime les entrées de la liste. Un garbage collection ultérieur déterminera que les objets finalisés sont véritablement nettoyés, car les entrées figurant dans la liste des objets marqués comme étant prêts pour la finalisation ne pointent plus vers eux. C'est au cours de ce garbage collection ultérieur que la mémoire de l'objet est en fait récupérée.
Voir aussi
Référence
Concepts
Substitution de la méthode Finalize
Syntaxe de destructeur en langage C# et C++