J'ai un script de longue durée qui, s'il s'exécute suffisamment longtemps, consommera toute la mémoire de mon système.
Sans entrer dans les détails du script, j'ai deux questions:
- Y a-t-il des «meilleures pratiques» à suivre, qui aideront à empêcher les fuites de se produire?
- Quelles techniques existe-t-il pour déboguer les fuites de mémoire en Python?
python
debugging
memory-management
memory-leaks
Fragsworth
la source
la source
__del__
méthode qui ne sont plus référencés sauf pour leur cycle. Le cycle ne peut pas être interrompu en raison de problèmes avec__del__
. Répare le!Réponses:
Jetez un œil à cet article: Traçage des fuites de mémoire python
Notez également que le module de garbage collection peut avoir des indicateurs de débogage définis. Regardez la
set_debug
fonction. En outre, regardez ce code de Gnibbler pour déterminer les types d'objets qui ont été créés après un appel.la source
J'ai essayé la plupart des options mentionnées précédemment mais j'ai trouvé que ce petit package intuitif était le meilleur: pympler
Il est assez simple de tracer des objets qui n'ont pas été récupérés, consultez ce petit exemple:
installer le package via
pip install pympler
La sortie vous montre tous les objets qui ont été ajoutés, plus la mémoire qu'ils ont consommée.
Exemple de sortie:
Ce package fournit un certain nombre de fonctionnalités supplémentaires. Consultez la documentation de pympler , en particulier la section Identifier les fuites de mémoire .
la source
pympler
peut être LENT . Si vous faites quelque chose en semi-temps réel, cela peut complètement paralyser les performances de votre application.Permettez-moi de recommander l' outil mem_top que j'ai créé
Cela m'a aidé à résoudre un problème similaire
Il montre juste instantanément les principaux suspects de fuites de mémoire dans un programme Python
la source
Le module Tracemalloc a été intégré en tant que module intégré à partir de Python 3.4, et apparemment, il est également disponible pour les versions précédentes de Python en tant que bibliothèque tierce (je ne l'ai pas testé cependant).
Ce module est capable de sortir les fichiers et les lignes précis qui ont alloué le plus de mémoire. À mon humble avis, cette information est infiniment plus précieuse que le nombre d'instances allouées pour chaque type (ce qui finit par être beaucoup de tuples 99% du temps, ce qui est un indice, mais aide à peine dans la plupart des cas).
Je vous recommande d'utiliser le tracemalloc en combinaison avec de la pyrasite . 9 fois sur 10, exécuter l' extrait de code 10 dans une coque en pyrasite vous donnera suffisamment d'informations et d'indices pour réparer la fuite en 10 minutes. Pourtant, si vous ne parvenez toujours pas à trouver la cause de la fuite, la pyrasite-shell en combinaison avec les autres outils mentionnés dans ce fil vous donnera probablement plus d'indices. Vous devriez également jeter un coup d'œil à tous les assistants supplémentaires fournis par pyrasite (tels que la visionneuse de mémoire).
la source
Vous devriez particulièrement jeter un œil sur vos données globales ou statiques (données de longue durée).
Lorsque ces données augmentent sans restriction, vous pouvez également rencontrer des problèmes en Python.
Le garbage collector ne peut collecter que des données qui ne sont plus référencées. Mais vos données statiques peuvent raccorder des éléments de données qui doivent être libérés.
Un autre problème peut être les cycles de mémoire, mais au moins en théorie, le garbage collector devrait trouver et éliminer les cycles - du moins tant qu'ils ne sont pas accrochés à des données de longue durée.
Quels types de données de longue durée sont particulièrement gênants? Jetez un œil à toutes les listes et dictionnaires - ils peuvent grandir sans aucune limite. Dans les dictionnaires, vous pourriez même ne pas voir le problème venir car lorsque vous accédez aux dictionnaires, le nombre de clés dans le dictionnaire peut ne pas être très visible pour vous ...
la source
Pour détecter et localiser les fuites de mémoire pour les processus de longue durée, par exemple dans les environnements de production, vous pouvez désormais utiliser stackimpact . Il utilise tracemalloc en dessous. Plus d'informations dans cet article .
la source
En ce qui concerne les meilleures pratiques, gardez un œil sur les fonctions récursives. Dans mon cas, j'ai rencontré des problèmes de récursivité (là où il n'y en avait pas besoin). Un exemple simplifié de ce que je faisais:
fonctionner de cette manière récursive ne déclenchera pas le ramasse-miettes et n'effacera pas les restes de la fonction, donc à chaque fois que l'utilisation de la mémoire augmente et augmente.
Ma solution était de retirer l'appel récursif de my_function () et d'avoir main () gérer le moment de le rappeler. de cette façon, la fonction se termine naturellement et se nettoie après elle-même.
la source
Je ne suis pas sûr des «meilleures pratiques» pour les fuites de mémoire en python, mais python devrait effacer sa propre mémoire par son ramasse-miettes. Donc, je commencerais principalement par vérifier la liste circulaire de certains courts, car ils ne seront pas ramassés par le ramasse-miettes.
la source
Ce n'est en aucun cas un conseil exhaustif. Mais la première chose à garder à l'esprit lors de l'écriture dans le but d'éviter de futures fuites de mémoire (boucles) est de s'assurer que tout ce qui accepte une référence à un rappel doit stocker ce rappel comme une référence faible.
la source