Question

J'utilise boost :: shared_ptr dans mon application en C ++. Le problème de la mémoire est vraiment grave, et l'application prend grande quantité de mémoire.

Cependant, parce que je mets tous les objets newed dans un shared_ptr, lorsque les sorties d'application, ne peuvent être détectés des fuites de mémoire.

Il doit y avoir quelque chose comme maintenant la piscine std::vector<shared_ptr<> > ressources. Comment puis-je savoir qui détient le shared_ptr, lors du débogage?

Il est difficile de revoir la ligne de code en ligne. trop de code ...

Merci beaucoup!

Était-ce utile?

La solution

Vous ne pouvez pas savoir, en regardant seulement un shared_ptr, où les « pointeurs de frères et soeurs » sont. Vous pouvez tester si l'on est ou obtenir le unique() use_count(), parmi d'autres méthodes .

Autres conseils

L'utilisation généralisée populaire de shared_ptr entraînera presque inévitablement l'occupation de la mémoire non désirée et invisible.

références cycliques sont une cause bien connue et certains d'entre eux peuvent être indirects et difficiles à repérer en particulier dans le code complexe qui est travaillé par plus d'un programmeur; un programmeur peut décider d'un objet a besoin d'une référence à un autre comme une solution rapide et n'a pas le temps d'examiner tout le code pour voir s'il ferme un cycle. Ce risque est extrêmement sous-estimé.

Moins bien compris est le problème des références inédites. Si un objet est partagé à de nombreux shared_ptrs alors il ne sera pas détruite jusqu'à ce que chacun d'eux est mis à zéro ou est hors de portée. Il est très facile d'oublier une de ces références et finissent avec des objets invisibles qui rôdent dans la mémoire que vous avez pensé que vous aviez fini avec.

Bien que à proprement parler ne sont pas ces fuites de mémoire (cela va être libéré avant la fin du programme), ils sont tout aussi nocifs et plus difficiles à détecter.

Ces problèmes sont les conséquences des fausses déclarations opportunes: 1. Déclarer ce que vous voulez vraiment être propriétaire unique comme shared_ptr. scoped_ptr serait correcte mais toute autre référence à cet objet devra être un pointeur brut, ce qui pourrait être laissé ballants. 2. Déclarer ce que vous voulez vraiment être une référence observation passive shared_ptr. weak_ptr serait correct, mais vous les tracas de la convertir en share_ptr chaque fois que vous voulez utiliser.

Je pense que votre projet est un bel exemple du genre de problème que cette pratique peut vous prendre.

Si vous avez une application intensive de mémoire que vous avez vraiment besoin d'un seul propriétaire afin que votre conception peut contrôler explicitement la durée de vie de l'objet.

Avec un seul propriétaire opObject = NULL; va supprimer définitivement l'objet et il le fera maintenant.

Avec la propriété partagée spObject = NULL; ........ qui sait? ......

Une solution à ballants ou des références de pointeur intelligent circulaire que nous avons fait est de personnaliser la classe de pointeur intelligent pour ajouter un débogage seule fonction de comptabilité. Chaque fois qu'un pointeur intelligent ajoute une référence à un objet, il faut une trace de la pile et le met dans une carte dont chaque entrée garde la trace de

  1. L'adresse de l'objet alloué (ce que les points de pointeur à)
  2. Les adresses de chaque pointeur intelligent objet contenant une référence à l'objet
  3. Les stacktraces correspondantes du moment où chaque pointeur intelligent a été construit

Quand un pointeur intelligent est hors de portée, son entrée sur la carte est supprimé. Lorsque le dernier objet à un pointeur intelligent est détruit, l'objet obtient son entrée pointée sur la carte supprimée.

Ensuite, nous avons une commande « fuites de piste » avec deux fonctions: « [re] commencer le suivi des fuites » (ce qui efface toute la carte et activé le suivi si ce ne est pas déjà), et « impression références ouvertes », ce qui montre tout exceptionnelle références créées depuis pointeur intelligent la commande « start suivi des fuites » a été publié. Comme vous pouvez voir les traces de la pile de l'endroit où ces pointeurs intelligents sont entrées en être, vous pouvez facilement savoir exactement qui est maintenant de votre objet libéré. Il ralentit les choses lorsque son, donc nous ne laissons tout le temps.

Il est une bonne quantité de travail à mettre en œuvre, mais vaut vraiment la peine si vous avez une base de code où cela se produit beaucoup.

Vous pouvez rencontrer une fuite de mémoire de pointeur partagé par cycles. Ce qui se passe est vos objets partagés peuvent contenir des références à d'autres objets partagés qui conduisent finalement à l'original. Lorsque cela se produit le cycle conserve tous les chefs de référence à 1, même si personne ne peut accéder aux objets. La solution est pointeurs faibles .

Essayez refactorisation une partie de votre code afin que la propriété est plus explicitement exprimée par l'utilisation de pointeurs faibles au lieu de pointeurs partagés dans certains endroits.

Lorsque l'on regarde la hiérarchie de classe, il est possible de déterminer quelle classe devrait vraiment tenir un pointeur partagé et qui a simplement besoin que le faible, de sorte que vous pouvez éviter les cycles s'il y et si l'objet propriétaire « réel » est détruit, objets « non-propriétaire » aurait déjà été passé. S'il se avère que certains objets perdent des pointeurs trop tôt, il faut regarder dans la séquence de destruction d'objets dans votre application et de le corriger.

Vous tenez évidemment sur des références à vos objets dans votre application. Cela signifie que vous êtes, à dessein, de garder les choses en mémoire. Cela signifie, vous n'avez pas une fuite de mémoire. Une fuite de mémoire est quand la mémoire est allouée, et vous ne gardez pas une référence à son adresse.

En gros, vous devez regarder votre conception et comprendre pourquoi vous gardez tant d'objets et les données en mémoire, et comment pouvez-vous minimiser.

La seule possibilité que vous avez une fuite pseudo-mémoire est que vous créez plus d'objets que vous pensez que vous êtes. Essayez de mettre sur tous les points d'arrêt des déclarations contenant un « nouveau ». Voir si votre demande est en train de construire plus d'objets que vous pensiez qu'il devrait, et lire ce code.

Le problème est vraiment pas tant une mémoire fuite car il est un problème de la conception de votre application.

J'allais vous suggérons d'utiliser UMDH si vous êtes sur Windows. Il est un outil très puissant. Utilisez-le à trouver des allocations par transaction / période de temps que vous prévoyez d'être libéré puis trouver qui les détient.

Il y a plus d'informations sur cette réponse SO Trouvez des fuites de mémoire causées par des pointeurs intelligents

Il est impossible de dire quels objets propres shared_ptr à partir du programme. Si vous êtes sous Linux, un moyen sûr de déboguer les fuites de mémoire est le Valgrind outil - alors qu'il ne sera pas directement répondre à votre question, il dira où a été attribué la mémoire, ce qui est généralement suffisant pour régler le problème. J'imagine que Windows a des outils comparables, mais je suis ne sais pas lequel est le meilleur.

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