Quel profileur de mémoire Python est recommandé? [fermé]

671

Je veux connaître l'utilisation de la mémoire de mon application Python et je veux en particulier savoir quels blocs / portions de code ou objets consomment le plus de mémoire. La recherche Google montre qu'un commercial est le validateur de mémoire Python (Windows uniquement).

Et ceux open source sont PySizer et Heapy .

Je n'ai essayé personne, donc je voulais savoir lequel est le meilleur compte tenu:

  1. Donne la plupart des détails.

  2. Je dois apporter le moins ou pas de modifications à mon code.

Anurag Uniyal
la source
2
Pour trouver les sources de fuites, je recommande objgraph.
pi.
9
@MikeiLL Il y a une place pour des questions comme celles-ci: Recommandations logicielles
Poik
2
Cela se produit assez souvent pour que nous puissions plutôt migrer une question vers un autre forum.
zabumba
Un conseil: si quelqu'un utilise gae pour et veut vérifier l'utilisation de la mémoire - c'est un gros casse-tête, car ces outils n'ont rien sorti ou l'événement n'a pas commencé. Si vous souhaitez tester quelque chose de petit, déplacez la fonction que vous souhaitez tester vers un fichier séparé et exécutez ce fichier seul.
alexche8
4
Je recommande pympler
zzzeek

Réponses:

288

Heapy est assez simple à utiliser. À un moment donné de votre code, vous devez écrire ce qui suit:

from guppy import hpy
h = hpy()
print(h.heap())

Cela vous donne une sortie comme celle-ci:

Partition of a set of 132527 objects. Total size = 8301532 bytes.
Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
0  35144  27  2140412  26   2140412  26 str
1  38397  29  1309020  16   3449432  42 tuple
2    530   0   739856   9   4189288  50 dict (no owner)

Vous pouvez également savoir d'où les objets sont référencés et obtenir des statistiques à ce sujet, mais d'une manière ou d'une autre, les documents à ce sujet sont un peu rares.

Il existe également un navigateur graphique, écrit en Tk.

Torsten Marek
la source
24
Si vous êtes sur Python 2.7, vous aurez peut-être besoin de la version trunk de celui-ci: sourceforge.net/tracker/… ,pip install https://guppy-pe.svn.sourceforge.net/svnroot/guppy-pe/trunk/guppy
James Snyder
27
Les documents lourds sont ... pas bons. Mais j'ai trouvé cet article de blog très utile pour commencer: smira.ru/wp-content/uploads/2011/08/heapy.html
Joe Shaw
4
Remarque, heapy n'inclut pas la mémoire allouée dans les extensions python. Si quelqu'un a mis au point un mécanisme pour obtenir du tas pour inclure des boost::pythonobjets, ce serait bien de voir quelques exemples!
amos
34
En date du 2014-07-06, guppy ne prend pas en charge Python 3.
Quentin Pradet
5
Il existe une fourchette de guppy qui prend en charge Python 3 appelée guppy3.
David Foster du
385

Puisque personne ne l'a mentionné, je pointerai vers mon module memory_profiler qui est capable d'imprimer un rapport ligne par ligne de l'utilisation de la mémoire et fonctionne sous Unix et Windows (nécessite psutil sur ce dernier). La sortie n'est pas très détaillée mais le but est de vous donner un aperçu de l'endroit où le code consomme plus de mémoire et non une analyse exhaustive des objets alloués.

Après avoir décoré votre fonction avec @profileet exécuté votre code avec le -m memory_profilerdrapeau, il imprimera un rapport ligne par ligne comme ceci:

Line #    Mem usage  Increment   Line Contents
==============================================
     3                           @profile
     4      5.97 MB    0.00 MB   def my_func():
     5     13.61 MB    7.64 MB       a = [1] * (10 ** 6)
     6    166.20 MB  152.59 MB       b = [2] * (2 * 10 ** 7)
     7     13.61 MB -152.59 MB       del b
     8     13.61 MB    0.00 MB       return a
Fabian Pedregosa
la source
1
Pour mon cas d'utilisation - un simple script de manipulation d'image, pas un système complexe, qui a laissé des curseurs ouverts - c'était la meilleure solution. Très simple à déposer et à comprendre ce qui se passe, avec un minimum de gunk ajouté à votre code. Parfait pour les correctifs rapides et probablement aussi pour d'autres applications.
driftcatcher
10
Je trouve que memory_profiler est vraiment simple et facile à utiliser. Je veux faire du profilage par ligne et non par objet. Merci pour l'écriture.
tommy.carstensen
1
@FabianPedregosa comment la dose memory_profiler gère les boucles, peut-elle identifier le numéro d'itération de la boucle?
Glen Fletcher
3
Il identifie les boucles uniquement implicitement lorsqu'il essaie de signaler le montant ligne par ligne et qu'il trouve des lignes dupliquées. Dans ce cas, cela prendra juste le maximum de toutes les itérations.
Fabian Pedregosa
1
@FabianPedregosa Tamponne-t-il memory_profilersa sortie? Je fais peut-être quelque chose de mal, mais il semble qu'au lieu de vider le profil d'une fonction une fois terminée, il attend la fin du script.
Greenstick
80

Je recommande Dowser . Il est très facile à configurer et vous n'avez besoin d'aucune modification de votre code. Vous pouvez afficher le nombre d'objets de chaque type dans le temps, afficher la liste des objets en direct, afficher les références aux objets en direct, le tout à partir de l'interface Web simple.

# memdebug.py

import cherrypy
import dowser

def start(port):
    cherrypy.tree.mount(dowser.Root())
    cherrypy.config.update({
        'environment': 'embedded',
        'server.socket_port': port
    })
    cherrypy.server.quickstart()
    cherrypy.engine.start(blocking=False)

Vous importez memdebug et appelez memdebug.start. C'est tout.

Je n'ai pas essayé PySizer ou Heapy. J'apprécierais les critiques des autres.

MISE À JOUR

Le code ci-dessus est pour CherryPy 2.X, CherryPy 3.Xla server.quickstartméthode a été supprimée et engine.startne prend pas le blockingdrapeau. Donc, si vous utilisezCherryPy 3.X

# memdebug.py

import cherrypy
import dowser

def start(port):
    cherrypy.tree.mount(dowser.Root())
    cherrypy.config.update({
        'environment': 'embedded',
        'server.socket_port': port
    })
    cherrypy.engine.start()
sanxiyn
la source
3
mais est-ce seulement pour cherrypy, comment l'utiliser avec un script sinple?
Anurag Uniyal, le
13
Ce n'est pas pour CherryPy. Considérez CherryPy comme une boîte à outils GUI.
sanxiyn
1
fwiw, la page pysizer pysizer.8325.org semble recommander heapy, qui, selon elle, est similaire
Jacob Gabrielson
6
Il existe un port WSGI générique de Dowser appelé Dozer, que vous pouvez également utiliser avec d'autres serveurs Web: pypi.python.org/pypi/Dozer
Joe Shaw
2
cherrypy 3.1 a supprimé cherrypy.server.quickstart (), alors utilisez simplement cherrypy.engine.start ()
MatsLindh
66

Considérez la bibliothèque objgraph (voirhttp://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks pour un exemple d'utilisation).

Charles Duffy
la source
7
objgraph m'a aidé à résoudre un problème de fuite de mémoire auquel j'étais confronté aujourd'hui. objgraph.show_growth () était particulièrement utile
Ngure Nyaga
1
Moi aussi, j'ai trouvé objgraph vraiment utile. Vous pouvez faire des choses comme objgraph.by_type('dict')comprendre d'où dictviennent tous ces objets inattendus .
dino
18

Muppy est (encore un autre) Profiler d'utilisation de la mémoire pour Python. Cet ensemble d'outils se concentre sur l'identification des fuites de mémoire.

Muppy essaie d'aider les développeurs à identifier les fuites de mémoire des applications Python. Il permet de suivre l'utilisation de la mémoire pendant l'exécution et d'identifier les objets qui fuient. De plus, des outils sont fournis qui permettent de localiser la source des objets non libérés.

Serrano
la source
13

Je développe un profileur de mémoire pour Python appelé memprof:

http://jmdana.github.io/memprof/

Il vous permet de consigner et de tracer l'utilisation de la mémoire de vos variables lors de l'exécution des méthodes décorées. Il vous suffit d'importer la bibliothèque en utilisant:

from memprof import memprof

Et décorez votre méthode en utilisant:

@memprof

Voici un exemple sur l'apparence des tracés:

entrez la description de l'image ici

Le projet est hébergé dans GitHub:

https://github.com/jmdana/memprof

jmdana
la source
3
Comment est-ce que je l'utilise? Qu'est-ce que a, b, c?
tommy.carstensen
@ tommy.carstensen a, bet csont les noms des variables. Vous pouvez trouver la documentation sur github.com/jmdana/memprof . Si vous avez des questions, n'hésitez pas à soumettre un problème dans github ou à envoyer un e-mail à la liste de diffusion qui se trouve dans la documentation.
jmdana
12

J'ai trouvé que meliae était beaucoup plus fonctionnel que Heapy ou PySizer. S'il vous arrive d'exécuter une webapp wsgi, alors Dozer est un joli wrapper middleware de Dowser

Calen Pennington
la source
8

Essayez également le projet pytracemalloc qui fournit l'utilisation de la mémoire par numéro de ligne Python.

EDIT (2014/04): Il dispose désormais d'une interface graphique Qt pour analyser les instantanés.

haypo
la source
4
tracemallocfait maintenant partie de la bibliothèque standard de python. Voir docs.python.org/3/library/tracemalloc.html
Dan Milon