Welcher Python-Speicherprofiler wird empfohlen? [geschlossen]

668

Ich möchte die Speichernutzung meiner Python-Anwendung kennen und insbesondere wissen, welche Codeblöcke / -teile oder -objekte den meisten Speicher belegen. Die Google-Suche zeigt, dass ein kommerzieller Python Memory Validator (nur Windows) ist.

Und Open Source sind PySizer und Heapy .

Ich habe noch niemanden ausprobiert, deshalb wollte ich wissen, welches das beste ist, wenn man bedenkt:

  1. Gibt die meisten Details.

  2. Ich muss am wenigsten oder gar keine Änderungen an meinem Code vornehmen.

Anurag Uniyal
quelle
2
Um die Ursachen von Lecks zu finden, empfehle ich objgraph.
pi.
9
@ MikeiLL Es gibt einen Platz für Fragen wie diese: Software-Empfehlungen
Poik
2
Dies geschieht häufig genug, damit wir stattdessen eine Frage in ein anderes Forum migrieren können.
Zabumba
Ein Tipp: Wenn jemand gae verwendet, um die Speichernutzung zu überprüfen, möchte er große Kopfschmerzen haben, da diese Tools nichts ausgegeben haben oder das Ereignis nicht gestartet wurde. Wenn Sie etwas Kleines testen möchten, verschieben Sie die zu testende Funktion in eine separate Datei und führen Sie diese Datei alleine aus.
Alexche8
4
Ich empfehle Pympler
Zzzeek

Antworten:

286

Heapy ist recht einfach zu bedienen. Irgendwann in Ihrem Code müssen Sie Folgendes schreiben:

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

Dies gibt Ihnen eine Ausgabe wie folgt:

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)

Sie können auch herausfinden, wo auf Objekte verwiesen wird, und Statistiken darüber abrufen, aber irgendwie sind die Dokumente dazu etwas spärlich.

Es gibt auch einen grafischen Browser, der in Tk geschrieben ist.

Torsten Marek
quelle
24
Wenn Sie mit Python 2.7 arbeiten, benötigen Sie möglicherweise die Trunk-Version: sourceforge.net/tracker/… ,pip install https://guppy-pe.svn.sourceforge.net/svnroot/guppy-pe/trunk/guppy
James Snyder
27
Die Heap-Dokumente sind ... nicht gut. Aber ich fand diesen Blog-Beitrag sehr hilfreich für den Einstieg: smira.ru/wp-content/uploads/2011/08/heapy.html
Joe Shaw
4
Beachten Sie, dass Heapy keinen in Python-Erweiterungen zugewiesenen Speicher enthält. Wenn jemand einen Mechanismus ausgearbeitet hat, um die Aufnahme von boost::pythonObjekten zu verbessern , wäre es schön, einige Beispiele zu sehen!
Amos
34
Ab dem 06.07.2014 unterstützt Guppy Python 3 nicht.
Quentin Pradet
5
Es gibt eine Guppy-Gabel, die Python 3 unterstützt und Guppy3 heißt.
David Foster
383

Da es niemand erwähnt hat, verweise ich auf mein Modul memory_profiler, das zeilenweise Berichte über die Speichernutzung drucken kann und unter Unix und Windows funktioniert (benötigt psutil für dieses letzte Modul). Die Ausgabe ist nicht sehr detailliert, aber das Ziel ist es, Ihnen einen Überblick darüber zu geben, wo der Code mehr Speicher verbraucht, und keine erschöpfende Analyse der zugewiesenen Objekte.

Nachdem Sie Ihre Funktion mit dekoriert @profileund Ihren Code mit dem -m memory_profilerFlag ausgeführt haben, wird ein zeilenweiser Bericht wie folgt gedruckt:

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
quelle
1
Für meinen Anwendungsfall - ein einfaches Bildbearbeitungsskript, kein komplexes System, bei dem einige Cursor offen blieben - war dies die beste Lösung. Sehr einfach, vorbeizuschauen und herauszufinden, was los ist, mit minimalem Aufwand, der Ihrem Code hinzugefügt wird. Perfekt für schnelle Lösungen und wahrscheinlich auch für andere Anwendungen.
Driftcatcher
10
Ich finde memory_profiler sehr einfach und benutzerfreundlich. Ich möchte eine Profilerstellung pro Zeile und nicht pro Objekt durchführen. Danke für's schreiben.
Tommy.carstensen
1
@FabianPedregosa Wie behandelt Dose Memory_Profiler Schleifen? Kann es die Schleifeniterationsnummer identifizieren?
Glen Fletcher
3
Schleifen werden nur implizit identifiziert, wenn versucht wird, den zeilenweisen Betrag zu melden, und doppelte Zeilen gefunden werden. In diesem Fall wird nur das Maximum aller Iterationen benötigt.
Fabian Pedregosa
1
@FabianPedregosa Puffert memory_profilerdie Ausgabe? Ich mache vielleicht etwas falsch, aber es scheint, dass das Profil nicht für eine Funktion ausgegeben wird, wenn es abgeschlossen ist, sondern auf das Ende des Skripts wartet.
Greenstick
80

Ich empfehle Dowser . Es ist sehr einfach einzurichten und Sie müssen keine Änderungen an Ihrem Code vornehmen. Über die einfache Weboberfläche können Sie die Anzahl der Objekte jedes Typs im Laufe der Zeit anzeigen, eine Liste der Live-Objekte anzeigen und Verweise auf Live-Objekte anzeigen.

# 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)

Sie importieren memdebug und rufen memdebug.start auf. Das ist alles.

Ich habe PySizer oder Heapy nicht ausprobiert. Ich würde mich über die Bewertungen anderer freuen.

AKTUALISIEREN

Der obige Code ist für CherryPy 2.X, CherryPy 3.Xdie server.quickstartMethode wurde entfernt und engine.startnimmt das blockingFlag nicht an . Also, wenn Sie verwendenCherryPy 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
quelle
3
Aber ist es nur für Cherrypy, wie man es mit einem einfachen Skript verwendet?
Anurag Uniyal
13
Es ist nicht für CherryPy. Stellen Sie sich CherryPy als GUI-Toolkit vor.
Sanxiyn
1
fwiw, die pysizer Seite pysizer.8325.org scheint heapy zu empfehlen, was es ähnlich sagt
Jacob Gabrielson
6
Es gibt einen generischen WSGI-Port von Dowser namens Dozer, den Sie auch mit anderen Webservern verwenden können: pypi.python.org/pypi/Dozer
Joe Shaw
2
cherrypy 3.1 entfernte cherrypy.server.quickstart (), also benutze einfach cherrypy.engine.start ()
MatsLindh
66

Betrachten Sie die Objektbibliothek (siehehttp://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks für einen beispielhaften Anwendungsfall).

Charles Duffy
quelle
7
objgraph hat mir geholfen, ein Problem mit Speicherverlusten zu lösen, mit dem ich heute konfrontiert war. objgraph.show_growth () war besonders nützlich
Ngure Nyaga
1
Auch ich fand objgraph wirklich nützlich. Sie können Dinge tun, um objgraph.by_type('dict')zu verstehen, woher all diese unerwarteten dictObjekte kommen.
Dino
18

Muppy ist (noch ein weiterer) Memory Usage Profiler für Python. Der Schwerpunkt dieses Toolset liegt auf der Identifizierung von Speicherlecks.

Muppy versucht Entwicklern dabei zu helfen, Speicherlecks in Python-Anwendungen zu identifizieren. Es ermöglicht die Verfolgung der Speichernutzung zur Laufzeit und die Identifizierung von Objekten, die undicht sind. Darüber hinaus werden Tools bereitgestellt, mit denen die Quelle nicht freigegebener Objekte gefunden werden kann.

Serrano
quelle
13

Ich entwickle einen Speicherprofiler für Python namens memprof:

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

Sie können die Speichernutzung Ihrer Variablen während der Ausführung der dekorierten Methoden protokollieren und grafisch darstellen. Sie müssen die Bibliothek nur importieren mit:

from memprof import memprof

Und dekorieren Sie Ihre Methode mit:

@memprof

Dies ist ein Beispiel dafür, wie die Diagramme aussehen:

Geben Sie hier die Bildbeschreibung ein

Das Projekt wird in GitHub gehostet:

https://github.com/jmdana/memprof

jmdana
quelle
3
Wie benutze ich es? Was ist a, b, c?
Tommy.carstensen
@ tommy.carstensen a, bund csind die Namen der Variablen. Die Dokumentation finden Sie unter github.com/jmdana/memprof . Wenn Sie Fragen haben, können Sie gerne ein Problem in github einreichen oder eine E-Mail an die Mailingliste senden, die Sie in der Dokumentation finden.
jmdana
12

Ich fand Meliae viel funktionaler als Heapy oder PySizer. Wenn Sie zufällig eine wsgi-Webanwendung ausführen, ist Dozer ein netter Middleware-Wrapper von Dowser

Calen Pennington
quelle
8

Probieren Sie auch das pytracemalloc-Projekt aus , das die Speichernutzung pro Python-Zeilennummer bereitstellt.

EDIT (2014/04): Es hat jetzt eine Qt-GUI zur Analyse von Schnappschüssen.

Haypo
quelle
4
tracemallocist jetzt Teil der Python-Standardbibliothek. Siehe docs.python.org/3/library/tracemalloc.html
Dan Milon