Question

  

Le destructeur ne doit libérer que les ressources non gérées que votre objet détient, et ne doit pas faire référence à d'autres objets. Si vous avez uniquement des références gérées, vous n'avez pas besoin (et ne devriez pas) implémenter un destructeur. Vous ne voulez cela que pour gérer des ressources non gérées. Étant donné que le destructeur a un coût , vous ne devriez le mettre en œuvre que sur des méthodes qui consomment des ressources précieuses non gérées.

     

- Les dix principaux pièges en C # pour C ++ Programmeurs

L'article n'entre pas dans les détails, mais quels sont les coûts liés à l'utilisation d'un destructeur en C #?

Remarque: Je connais le GC et le fait que le destructeur ne soit pas appelé à des moments fiables, à part cela, y at-il autre chose?

Était-ce utile?

La solution

Tout objet doté d'un finaliseur (je préfère ce terme plutôt que destructeur, pour souligner la différence par rapport aux destructeurs C ++) est ajouté à la file d'attente du finaliseur. Voici une liste de références aux objets comportant un finaliseur à appeler avant de les supprimer.

Lorsque l'objet est prêt pour la récupération de place, le CPG détecte qu'il se trouve dans la file d'attente du finaliseur et déplace la référence vers la file d'attente accessible à la lecture (accessible à f). Il s’agit de la liste parcourue par le thread d’arrière-plan du finaliseur pour appeler tour à tour la méthode de finalisation de chaque objet.

Une fois le finaliseur de l'objet appelé, celui-ci n'est plus dans la file d'attente du finaliseur; il ne s'agit donc que d'un objet géré standard que le GC peut supprimer.

Tout cela signifie que si un objet a un finaliseur, il survivra à au moins un ramasse-miettes avant de pouvoir être supprimé. Cela signifie généralement que l'objet sera déplacé vers la génération de tas suivante, ce qui implique le déplacement des données en mémoire d'un tas à un autre.

Autres conseils

La discussion la plus longue que j'ai eue Joe Duffy a expliqué comment tout cela fonctionnait . Il contient plus de détails que vous ne pouvez l’imaginer.

Par la suite, j’ai mis au point une approche pratique pour le faire au quotidien - moins de coûts, mais plus de mise en œuvre.

Guffa et JaredPar couvrent assez bien les détails, je vais donc ajouter une note quelque peu ésotérique sur les finaliseurs ou les destructeurs, car la spécification du langage C # les appelle malheureusement.

Une chose à garder à l’esprit est que, puisque le processus de finalisation exécute tous les finaliseurs en séquence, une impasse dans un finaliseur empêchera tous les finaliseurs restants (et futurs) de s'exécuter. Étant donné que ces instances ne sont pas collectées tant que leurs finaliseurs ne sont pas terminés, un finaliseur bloqué provoquera également une fuite de mémoire.

Cet article traite le problème en détail. Il est très difficile de résumer un simple message SO: http: // msdn. microsoft.com/en-us/magazine/bb985010.aspx

Guffa a très bien résumé les facteurs du coût du finaliseur. Il existe un article récent sur le coût des finaliseurs en Java, qui donne également un aperçu.

Une partie du coût en .net peut être évitée en supprimant l'objet de la file d'attente du finaliseur avec GC.SuppressFinalize. J'ai effectué quelques tests rapides sur .net, basés sur des articles, et je les ai publiés ici (bien que l’accent soit mis beaucoup plus sur le côté Java).

Ci-dessous, un graphique des résultats - il n’a pas vraiment les meilleures étiquettes ;-). " Debug = true / false " fait référence au finaliseur vide vs simple:

~ConditionalFinalizer()  
{  
    if (DEBUG)  
    {  
        if (!resourceClosed)  
        {  
            Console.Error.WriteLine("Object not disposed");  
        }  
        resourceClosed = true;  
    }  
} 

" Suppress = true " indique si GC.SuppressFinalize a été appelé dans la méthode Dipose.

Résumé

Pour .net, supprimer l'objet de la file d'attente du finaliseur en appelant GC.SuppressFinalize est deux fois moins coûteux que de laisser l'objet dans la file d'attente.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top