2009-09-26 7 views
4

Question: devrais-je écrire destructor pour un singleton quiDestructeur pour Singleton

a la portée du programme (se anime quand programme démarre et meurt quand la fin du programme) Détail:

je suis dans un dilemme sur

"dois-je écrire destructor pour une classe singleton ou pas?"

1) Cette classe a la portée du programme 2) Classe utilise beaucoup de mémoire sur tas, libérant donc cela prendra du temps

Lorsque l'utilisateur est le programme de quitter, la réponse doit être rapide, alors pourquoi passer du temps dans libérer de la mémoire occupée par ce singleton, car la mémoire sera libérée au fur et à mesure que le programme se terminera.

+0

Quel est « rapide » dans «la réponse devrait être rapide? –

+0

@dribeas: Peut-être, réponse rapide de l'appel 'wait()' dans la communication inter-processus? –

Répondre

3

Si la libération de la mémoire prend beaucoup de temps, ne le faites pas. Cela peut être un gros problème et prendre beaucoup de temps, surtout si la libération de la mémoire mène à de nombreux échecs de cache. OS fera le travail (bien sûr, si vous travaillez sur les systèmes qui le font). Toutefois, si votre destructeur finalise certaines ressources (par exemple, déverrouiller un fichier ou un composant matériel) et que vous utilisez l'initialisation de l'acquisition de ressources, vous devez vous assurer que les destructeurs appropriés sont appelés (par exemple: http://www.microsoft.com/downloads/docs/docs/docs/display.aspx?hl=fr , ceux des objets statiques sont appelés après vos retours de fonction main()). Ceci est vrai si certains des objets alloués à l'intérieur de votre singleton verrouillent aussi les ressources!

Dans la plupart des cas, donc, il vaut mieux en fait écrire un destructor pour un tel objet et de le rendre libérer de la mémoire en option .


SSS, qui a posé la question, a décidé de ne pas écrire destructor du tout. Cependant, je voudrais dire un peu plus que ce n'est pas la meilleure solution. Le fait de ne pas libérer de mémoire pour un objet statique (appelons-le "statique") est une optimisation très subtile qui contredit le bon sens et la façon dont les gens écrivent habituellement des programmes. Votre code, l'allocation de la mémoire et simplement n'ayant pas de destructeur, regarde bizarre. Les pairs penseront que la classe est mal écrite, aura tendance à regarder les bugs dedans (alors qu'ils sont dans l'autre classe).Au lieu de cela, vous devez vous conformer aux normes de codage courantes qui exigent que la gestion de la mémoire en C++ soit correcte. Ecrivez un destructeur et, seulement après qu'il montre qu'il a une amélioration significative pour ne pas le libérer, enveloppez le code pour qu'il ne soit pas appelé.

L'intention de ne pas libérer la mémoire doit être explicite.

MySingleton::~MySingleton() 
{ 
#ifndef RELEASE 
    // The memory will be released by OS when program terminates! 
    delete ptr1; 
    delete ptr2; 
#endif 
} 

ou même

MySingleton::~MySingleton() 
{ 
    // We don't do anything here. 
    // The memory will be released by OS when program terminates! 
} 

mais destructor est préférable de persister.

+0

vous avez raison: a) Destructeur prend beaucoup de temps pour supprimer toute hiérarchie b) Son un seul thread et ne détiennent aucune responsabilité pour finalzing toute ressource je dois donc décider de ne pas écrire une destructor, pour une meilleure utilisation expérience lors de la fermeture de l'application – Satbir

+0

:) Cher Pavel, je respecte vos pensées, je suis d'accord, il va avoir l'air bizarre. Je suis déjà l'idée suivante de "Intention de ne pas libérer la mémoire doit être explicite" Aussi, je vais avoir des avertissements pour les fuites de mémoire. Mais je vois un coup de pouce de ~ 300 millisecondes sur mon cpu 2GhZ, ce sera moins sur la machine principale qui a un processeur Xenon. – Satbir

0

Si vous utilisez sous Windows OS, toute la mémoire/ressources occupées par tout processus seront remises en état lorsque l'application se ferme donc à mon humble avis, il n'a pas d'importance

+2

Techniquement, tous les systèmes d'exploitation devraient le faire, mais je tiens à souligner que Windows est le gestionnaire de mémoire le plus bogué que j'ai vu utilisé depuis longtemps.Je l'ai vu échouer à de telles tâches, mais pas si mal dans les versions plus récentes de Windows. – ewanm89

+2

Peut-être que vous pourriez soutenir cette affirmation avec un fait? Donner un exemple d'une situation où Windows (toute version à partir de 2000) ne parvient pas à récupérer la mémoire. Sinon, vous ne faites que répandre votre propre ignorance. – jalf

-2

Comme l'a souligné le système d'exploitation devrait libérer de la mémoire à la fin de toute façon Cependant, voulez-vous vraiment lui faire confiance pour le gérer? Au moins avec une destruction explicite, un gestionnaire de mémoire bogué/mal conçu a plus de chance de faire les choses correctement.

Il y a deux chances de réussir.

+0

En supposant que votre système d'exploitation le supporte, vous pouvez absolument compter sur le gestionnaire de mémoire du système d'exploitation pour détruire complètement l'espace d'adressage virtuel d'un processus. Cela se passe à un niveau conceptuel différent de celui de C++ Freestore. – TheFogger

+0

J'ai vu plusieurs exemples lorsque de tels gestionnaires de mémoire ont échoué à effectuer une telle tâche. Cela dépend de divers facteurs, théoriquement oui cela devrait fonctionner. Souvenez-vous que le gestionnaire de mémoire du noyau s'inquiète de savoir si c'est de la mémoire partagée entre plusieurs processus et autres. Un bug peut les amener à maltraiter la mémoire dans certains cas. – ewanm89

+0

Je dis que si on gère la mémoire de toute façon, on dépend moins de quelque chose qui pourrait potentiellement être un noyau brisé. – ewanm89

2

Il semble que vous créez un God Object, il serait donc bénéfique de reconsidérer la conception de votre classe.

Que vous ajoutiez ou non un destructeur dépend de la valeur ou non de la performance pour libérer, et éventuellement réallouer, la mémoire.

+1

Si SSS croit en Dieu, pourquoi pas? ;-) –

+1

Je ne suggère certainement pas que cela ne marcherait pas - juste essayer de le sauver, ou ceux qui vont maintenir l'application, quelques maux de tête à l'avenir. –

2

Le langage C++ ne garantit pas que la mémoire sera récupérée à la fin du programme, mais tout système d'exploitation à moitié décent le fera sans problème.

Alors oui, si

  • vous exécutez sur un demi-OS décent et
  • il n'y a rien d'autre le destructor devrait faire que libérer la mémoire

alors oui, vous pouvez omettre le destructeur, fuir la mémoire, et compter sur le système d'exploitation pour nettoyer après vous. L'inconvénient évident à cela est que divers outils de débogage peuvent crier et crier sur les fuites de mémoire.

Bien sûr, une question un peu plus fondamentale est pourquoi créez-vous un singleton qui alloue autant de mémoire?

Cela me semble être une conception terrible.

+0

je suis d'accord c'est la conception terrible, Mais le système est très stable .. Je ne vais pas obtenir une permission de changer de conception :) .. – Satbir

+0

C'est juste. :) – jalf

2

Implémentez le destructeur comme c'est la bonne façon et sera la version la plus maintenable. Ensuite, mesurez (créez un exécutable qui crée simplement le singleton et quittez) le temps réel nécessaire pour libérer la mémoire. Une fois que vous avez des informations précises sur le coût d'une suppression correcte, n'écrivez pas de code incorrect. Si cela prend un certain temps mesurable, considérez-le comme une mesure relative par rapport à la durée du programme. Dans la plupart des cas, le traitement requis pour l'application sera beaucoup plus que le temps nécessaire pour libérer la mémoire. Si vous pensez toujours que cela prend trop de temps, considérez ce qu'un utilisateur régulier considérera comme trop long, combien de fois l'application est ouverte et fermée par l'utilisateur, si cela correspond vraiment à quelque chose ou non. Si à la fin vous décidez que c'est trop, vous risquez que l'application soit modifiée ultérieurement, le singleton pourrait acquérir des ressources externes et ne pas les libérer, ce qui est particulièrement grave avec les verrous de fichiers. ..

Ceux qui sacrifient la correction pour la performance ne méritent ni