2010-11-14 9 views
11

Ich mache einige schwere Berechnungen mit Python (mit OpenCV und Numpy) und am Ende habe ich eine Menge Speicherverbrauch (> 1GB) wobei alle refs weg sein sollten und ich nur das Endergebnis habe (welches nicht mehr als ein paar MB betragen sollte).Python: Speicherauslastung Statistiken pro Objekt-Typen (oder Quellcodezeile)

Um dies zu debuggen, wäre es nett, wenn ich irgendwie Statistiken bekommen könnte, die mir zeigen, wie viele Objektinstanzen es von welchem ​​Typ gibt, sortiert nach der Gesamtspeichermenge (pro Objektklasse).

Oder noch netter: Nicht pro Objektklasse, aber pro Quellcodezeile, wo das Objekt erstellt wurde (wobei ich denke, dass diese Information nicht verfügbar ist, wenn ich ein Debugging in Python aktiviere, was die Berechnung zu langsam machen würde.) sicher, ob das hilfreich wäre).

Kann ich irgendwie solche Statistiken bekommen? Oder wie würde ich das debuggen?


Einige missunderstood mich hat: Ich nur müssen wissen, wie die Speichernutzung zu debuggen. Verarbeitung/Laufzeit ist perfekt.

+0

Für den Anfang finden http://docs.python.org/library/profile.html –

+0

Dies gilt nicht Ihre Frage beantworten, aber Blick auf \ _ \ _ Slots \ _ \ _ zur Reduzierung des Speicherverbrauchs. –

+0

@Rafe: Es scheint nur um die Laufzeit zu gehen, aber nicht um die Speichernutzung, oder? – Albert

Antwort

8

Ich denke, Sie suchen nach einem Python-Profiler;

Sie haben ein paar von ihnen, dass Sie verwenden können, wie Heapy, profile or cprofile, Pysize ...

Beispiel mit Heapy:

Sie in Ihrem Code diesen Schnipsel irgendwo enthalten haben:

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

und es wird Sie als Ausgabe geben:

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) 

Beispiel mit Cprofile:

Sie es wie folgt ausführen:

python -m cProfile script.py 

Ausgang:

  5 function calls in 0.000 CPU seconds 

    Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
     1 0.000 0.000 0.000 0.000 <string>:1(<module>) 
     1 0.000 0.000 0.000 0.000 myscript.py:1(<module>) 
     1 0.000 0.000 0.000 0.000 {execfile} 
     1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 
     1 0.000 0.000 0.000 0.000 {range} 

Sie auch gc Modul warum Python zu wissen, verwenden kann, ist nicht zu befreien Ihre Erinnerung, und um ihn zu bitten, Speicher unter Verwendung gc.collect() freizugeben.

Übrigens haben Sie sich numpy angesehen, ich denke, es ist besser geeignet, wenn Sie schwere Berechnung tun, wie Sie sagten.

+2

Ich sehe nicht ganz, wie ich aus cProfile Speicherstatistiken bekommen kann. Können Sie erklären? – Albert

+0

Heapy scheint von dem, was es zeigt, nützlicher zu sein. Es scheint jedoch keine korrekte Ausgabe zu geben. Es besagt, dass die Gesamtgröße etwa 8 MB beträgt. Der Vorgang dauert jedoch> 1 GB. – Albert

+0

Ich habe die Tools in Objgraph (beschrieben [hier] (http://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks)) und es gibt mir ähnliche Ausgabe. Aber ich frage mich, warum es keine 'str'-Referenzen gibt. Beide zeigen jedoch nicht, wo der größte Teil des Speichers tatsächlich ist (etwa 99% des realen Speichers fehlen in der Ausgabe). Vielleicht ist es ein Speicherleck in einer der externen Bibliotheken wie OpenCV oder Numpy? – Albert

6

Ok, ich habe es gejagt. Da keines der Python-Mem-Profile eine hilfreiche Ausgabe liefert (weil sie den Speicher nicht finden konnten), war ich ziemlich sicher, dass einige der externen Bibliotheken (OpenCV) die Quelle des mem-Lecks waren.

Und ich konnte die mem Leck mit diesem einfachen Code reproduzieren:

import cv 
while True: cv.CreateHist([40], cv.CV_HIST_ARRAY, [[0,255]], 1) 

Einige der anderen Ressourcen für Python mem-Debugging, die sehr interessant waren (war in diesem Fall nicht geholfen, sondern kann nützlich für andere):

Verwandte Themen