Question

Je viens juste de commencer à expérimenter SDL en C ++ et je pensais que la recherche régulière de fuites de mémoire pouvait être une bonne habitude à prendre tôt.

Dans cet esprit, j'ai exécuté mes programmes "Hello world" via Valgrind pour détecter toute fuite, et bien que j'ai tout supprimé, à l'exception des plus élémentaires SDL_Init () et SDL_Quit () , Valgrind signale toujours 120 octets perdus et 77 Ko toujours accessibles.

Ma question est la suivante: existe-t-il une limite acceptable de fuites de mémoire ou dois-je m'efforcer de rendre tout mon code totalement exempt de fuites?

Était-ce utile?

La solution

Veillez à ce que Valgrind ne détecte pas de faux positifs dans ses mesures.

De nombreuses implémentations naïves d'analyseurs de mémoire signalent que la mémoire perdue est une fuite quand ce n'est pas vraiment le cas.

Peut-être avez-vous lu certains des documents dans la section des liens externes de l'article de Wikipedia sur Purify . Je sais que la documentation fournie avec Purify décrit plusieurs scénarios dans lesquels vous obtenez des faux positifs lorsque vous essayez de détecter des fuites de mémoire, puis décrit les techniques que Purify utilise pour résoudre les problèmes.

BTW, je ne suis en aucun cas affilié à IBM. Je viens d'utiliser abondamment Purify et je vais en garantir l'efficacité.

Modifier: voici un excellent article d'introduction sur la mémoire surveillance. C'est purifier spécifique mais la discussion sur les types d'erreurs de mémoire est très intéressante.

HTH.

acclamations,

Rob

Autres conseils

Vous devez faire attention à la définition de "fuite de mémoire". Quelque chose qui est attribué une fois lors de la première utilisation et libéré à la sortie du programme est parfois signalé par un détecteur de fuite, car il a commencé à compter avant cette première utilisation. Mais ce n’est pas une fuite (bien que ce puisse être une mauvaise conception, car ce pourrait être une sorte de global).

Pour voir si un bloc de code donné fuit, vous pouvez raisonnablement l'exécuter une fois, puis effacer le détecteur de fuites, puis le réexécuter (cela nécessite bien sûr un contrôle programmé du détecteur de fuites). Les choses qui "fuient" une fois par cycle du programme n’importe généralement pas. Les choses qui "fuient" chaque fois qu’elles sont exécutées ont généralement de l’importance.

J'ai rarement trouvé trop difficile d'atteindre le zéro sur cette métrique, ce qui équivaut à observer l'utilisation de la mémoire qui rampe par opposition aux blocs perdus. J'avais une bibliothèque où il y avait tellement de problèmes, avec des caches, des meubles d'interface utilisateur et tout le reste, que je venais de lancer ma suite de tests trois fois et que je ne tenais compte d'aucune "fuite". qui n'a pas eu lieu dans des multiples de trois blocs. J'ai encore attrapé toutes ou presque toutes les fuites réelles, et analysé les rapports difficiles une fois que j'avais réussi à trouver le fruit du travail. Bien entendu, les faiblesses de l’utilisation de la suite de tests à cette fin sont (1) vous ne pouvez utiliser que les parties de celle-ci qui ne nécessitent pas de nouveau processus, et (2) la plupart des fuites que vous trouvez sont dues au code de test. , pas le code de la bibliothèque ...

Vivre avec des fuites de mémoire (et d’autres problèmes d'inattention) est, à son meilleur, (à mon avis) une très mauvaise programmation. Dans le pire des cas, le logiciel devient inutilisable.

Vous devriez éviter de les présenter en premier lieu et utiliser les outils que vous et d'autres avez mentionnés pour tenter de les détecter.

Évitez les programmations bâclées - il y a déjà assez de mauvais programmeurs - le monde n'en a pas besoin.

EDIT

Je suis d'accord. De nombreux outils peuvent générer des faux positifs.

Si vous craignez vraiment une fuite de mémoire, vous devrez effectuer certains calculs.

Vous devez tester votre application pendant une heure, puis calculer la mémoire perdue. De cette façon, vous obtenez une fuite d'octets mémoire / minute.

Maintenant, vous devrez estimer la durée moyenne de la session de votre programme. Par exemple, pour notepad.exe, 15 minutes me semblent une bonne estimation.

Si ( durée de session moyenne) * (octets / minute divulgués) > 0.3 * (espace mémoire normalement occupé par votre processus) , vous devriez alors probablement redoubler d'efforts pour réduire les fuites de mémoire. Je viens de faire 0,3, utilisez votre bon sens pour déterminer votre seuil acceptable.

N'oubliez pas qu'un aspect important du programmeur est d'être un ingénieur logiciel. Très souvent, l'ingénierie consiste à choisir la moins mauvaise des options parmi deux mauvaises ou plus. Les mathématiques sont toujours utiles lorsque vous devez mesurer la gravité d'une option.

Pour une application de bureau, les petites fuites de mémoire ne constituent pas un réel problème. Pour les services (serveurs), aucune fuite de mémoire n'est acceptable.

La plupart des systèmes d'exploitation (y compris Windows) restitueront toute la mémoire allouée à un programme lors du déchargement du programme. Ceci inclut toute mémoire dont le programme lui-même a peut-être perdu la trace.

Étant donné cela, ma théorie habituelle est qu'il est parfaitement correct de perdre de la mémoire au démarrage, mais pas de le faire pendant l'exécution.

Donc, vraiment, la question n'est pas de savoir si vous perdez de la mémoire , , mais plutôt si vous la perdez continuellement pendant l'exécution de votre programme. Si vous utilisez votre programme pendant un certain temps et que, quoi que vous fassiez, il reste à 120 octets perdus au lieu d'augmenter, je dirais que vous avez très bien réussi. Passez à autre chose.

Cela dépend de votre application. Certaines fuites peuvent être inévitables (en raison du temps nécessaire pour trouver la fuite et les délais). Tant que votre application peut s'exécuter aussi longtemps que vous le souhaitez et que vous ne devez pas utiliser une quantité folle de mémoire à ce moment-là, c'est probablement bien.

Il semble que les développeurs SDL n'utilisent pas Valgrind, mais je ne me soucie que de ces 120 octets perdus.

  

Dans cet esprit, j'ai exécuté mes programmes "Hello world" via Valgrind pour détecter toute fuite, et bien que j'aie tout supprimé, à l'exception des instructions les plus élémentaires SDL_Init () et SDL_Quit (), Valgrind indique toujours 120 octets perdus et 77k toujours accessibles.

Eh bien, avec Valgrind, "mémoire toujours accessible" est souvent pas vraiment une fuite de mémoire, en particulier dans un programme aussi simple. Je peux parier que SDL_Quit () n’est pour l’essentiel pas alloué, donc les "fuites" ne sont que des structures allouées une fois par SDL_Init ().

Essayez d’ajouter du travail utile et de voir si ces montants augmentent; essayez de faire une boucle de travail utile (comme créer et détruire une structure SDL) et voyez si le nombre de fuites augmente avec le nombre d'itérations. Dans ce dernier cas, vous devez vérifier les traces de la fuite dans la pile et les corriger.

Sinon, ces fuites de 77k comptent comme "mémoire qui doit être libérée à la fin du programme, mais pour laquelle elles dépendent du système d'exploitation pour le libérer.

Donc, en fait, je suis plus inquiet à l’heure actuelle par ces 120 octets, s’ils ne sont pas de faux positifs et qu’ils sont généralement peu nombreux. Les faux positifs avec Valgrind sont principalement des cas où l’utilisation de mémoire non initialisée est prévue (par exemple parce qu’elle est en train de remplir).

Conformément aux commentaires de Rob Wells sur Purify, téléchargez et testez d’autres outils. J'utilise BoundsChecker et AQTime et j'ai constaté différents faux positifs au cours des deux dernières années. Notez que la fuite de mémoire peut également provenir d'un composant tiers, que vous souhaiterez peut-être exclure de votre analyse. Par exemple, MFC présentait un certain nombre de fuites de mémoire dans les premières versions d’affichage.

Messieurs, les fuites de mémoire doivent être recherchées pour tout code entrant dans une base de code pouvant durer longtemps. Si vous ne pouvez pas les retrouver, notez au moins qu’ils existent pour le prochain utilisateur du même code.

Les premières fuites de mémoire ne sont un problème grave que lorsqu'elles se développent avec le temps, sinon l'application a l'air un peu plus grosse de l'extérieur (évidemment, il y a une limite ici aussi, d'où le "sérieux"). Lorsque vous avez une fuite qui se développe avec le temps, vous pourriez avoir des problèmes. Combien de problèmes dépend des circonstances bien. Si vous savez où va la mémoire et pouvez vous assurer que vous aurez toujours assez de mémoire pour exécuter le programme et tout le reste sur cette machine, vous êtes encore un peu en forme. Cependant, si vous ne savez pas où va la mémoire, je n’enverrais pas le programme et continuerais à creuser.

Avec SDL sous Linux en particulier, il semble y avoir des fuites dans la bibliothèque X Windows sous-jacente. Vous ne pouvez rien y faire (à moins que vous ne vouliez essayer de réparer la bibliothèque elle-même, ce qui n’est probablement pas pour les âmes sensibles).

Vous pouvez utiliser le mécanisme de suppression de valgrind (voir --suppressions et --gen-suppressions dans la page de manuel valgrind) pour lui éviter de vous déranger avec ces erreurs.

En général, nous devons être un peu plus indulgents avec les bibliothèques tierces; alors que nous ne devrions absolument pas accepter les fuites de mémoire dans notre propre code, et que la présence de fuites de mémoire devrait être un facteur à prendre en compte lors du choix entre des bibliothèques tierces tierces, il n’ya parfois pas d’autre choix que de les ignorer (bien que cela puisse être une bonne idée de les signaler) responsable de la bibliothèque).

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