Który profiler pamięci Python jest zalecany? [Zamknięte]

670

Chcę poznać wykorzystanie pamięci przez moją aplikację Python, a konkretnie chcę wiedzieć, które bloki / części kodu lub obiekty zużywają najwięcej pamięci. Wyszukiwarka Google pokazuje, że komercyjnym jest Python Memory Validator (tylko Windows).

A te open source to PySizer i Heapy .

Nie próbowałem nikogo, więc chciałem wiedzieć, który jest najlepszy, biorąc pod uwagę:

  1. Podaje większość szczegółów.

  2. Muszę wprowadzać lub nie wprowadzać żadnych zmian w kodzie.

Anurag Uniyal
źródło
2
Aby znaleźć źródła wycieków, polecam objgraph.
pi.
9
@MikeiLL Jest miejsce na takie pytania: Zalecenia dotyczące oprogramowania
Poik
2
Dzieje się tak często, że zamiast tego powinniśmy móc przenieść jedno pytanie na inne forum.
zabumba
Jedna wskazówka: jeśli ktoś używa gae i chce sprawdzić użycie pamięci - to duży ból głowy, ponieważ te narzędzia nie generowały niczego lub nie rozpoczęło się zdarzenie. Jeśli chcesz przetestować coś małego, przenieś funkcję, którą chcesz przetestować, do osobnego pliku i uruchom ten plik sam.
alexche8
4
Polecam pympler
zzzeek

Odpowiedzi:

288

Heapy jest dość prosty w użyciu. W pewnym momencie kodu musisz napisać:

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

Daje to trochę takich wyników:

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)

Możesz również dowiedzieć się, skąd się odwołują obiekty i uzyskać statystyki na ten temat, ale dokumenty na ten temat są nieco rzadkie.

Istnieje również przeglądarka graficzna napisana w Tk.

Torsten Marek
źródło
24
Jeśli korzystasz z Pythona 2.7, możesz potrzebować jego wersji trunk: sourceforge.net/tracker/… ,pip install https://guppy-pe.svn.sourceforge.net/svnroot/guppy-pe/trunk/guppy
James Snyder
27
Heapy docs ... nie są dobre. Uważam jednak, że ten wpis na blogu jest bardzo pomocny na początku: smira.ru/wp-content/uploads/2011/08/heapy.html
Joe Shaw
4
Uwaga: heapy nie obejmuje pamięci przydzielonej w rozszerzeniach Pythona. Jeśli ktoś opracował mechanizm pozwalający heapy na dołączanie boost::pythonprzedmiotów, dobrze byłoby zobaczyć kilka przykładów!
amos
34
W dniu 06.07.2014 guppy nie obsługuje Python 3.
Quentin Pradet
5
Istnieje guppy, który obsługuje Python 3 o nazwie guppy3.
David Foster
385

Ponieważ nikt o tym nie wspominał, wskażę mój moduł memory_profiler, który jest w stanie drukować raport liniowy po zużyciu pamięci i działa na systemach Unix i Windows (na tym ostatnim wymaga psutil). Dane wyjściowe nie są bardzo szczegółowe, ale ich celem jest przegląd sytuacji, w której kod zużywa więcej pamięci, a nie wyczerpująca analiza przydzielonych obiektów.

Po udekorowaniu funkcji @profilei uruchomieniu kodu z -m memory_profilerflagą, wydrukuje on raport wiersz po wierszu w następujący sposób:

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
źródło
1
Dla mojego przypadku - prosty skrypt do manipulacji obrazami, a nie skomplikowany system, przez co niektóre kursory pozostały otwarte - to było najlepsze rozwiązanie. Bardzo łatwo wpaść i dowiedzieć się, co się dzieje, z minimalną porcją dodaną do kodu. Idealny do szybkich poprawek i prawdopodobnie także do innych aplikacji.
driftcatcher
10
Uważam, że memory_profiler jest naprawdę prosty i łatwy w użyciu. Chcę profilować według linii, a nie według obiektu. Dziękuję za napisanie.
tommy.carstensen
1
@FabianPedregosa, w jaki sposób dawka_profiler obsługuje pętle, czy może identyfikować numer iteracji pętli?
Glen Fletcher
3
Identyfikuje pętle tylko pośrednio, gdy próbuje zgłosić kwotę po linii i znajduje zduplikowane linie. W takim przypadku zajmie to maksimum wszystkich iteracji.
Fabian Pedregosa
1
@FabianPedregosa Czy memory_profilerbuforuje dane wyjściowe? Mogę robić coś złego, ale wydaje się, że zamiast zrzucić profil funkcji po jej zakończeniu, czeka na zakończenie skryptu.
Greenstick
80

Polecam Dowser . Jest bardzo łatwy w konfiguracji i nie wymaga żadnych zmian w kodzie. Możesz przeglądać liczbę obiektów każdego typu w czasie, przeglądać listę obiektów aktywnych, przeglądać odniesienia do obiektów aktywnych, wszystko z prostego interfejsu internetowego.

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

Importujesz memdebug i wywołujesz memdebug.start. To wszystko.

Nie próbowałem PySizer ani Heapy. Byłbym wdzięczny za recenzje innych.

AKTUALIZACJA

Powyższy kod jest CherryPy 2.X, metoda została usunięta i nie bierze flagę. Więc jeśli używaszCherryPy 3.Xserver.quickstartengine.startblockingCherryPy 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
źródło
3
ale czy to tylko dla cherrypy, jak używać go ze skromnym skryptem?
Anurag Uniyal
13
To nie jest dla CherryPy. Pomyśl o CherryPy jako zestawie narzędzi GUI.
sanxiyn
1
fwiw, strona pysizer pysizer.8325.org wydaje się zalecać heapy, które, jak mówi, jest podobne
Jacob Gabrielson,
6
Istnieje ogólny port WSGI programu Dowser o nazwie Dozer, którego można również używać z innymi serwerami WWW: pypi.python.org/pypi/Dozer
Joe Shaw
2
cherrypy 3.1 usunął cherrypy.server.quickstart (), więc po prostu użyj cherrypy.engine.start ()
MatsLindh 24.01.2013
66

Rozważmy bibliotekę objgraph (patrzhttp://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks na przykładowy przypadek użycia).

Charles Duffy
źródło
7
objgraph pomógł mi rozwiązać problem wycieku pamięci, z którym miałem dzisiaj do czynienia. objgraph.show_growth () był szczególnie przydatny
Ngure Nyaga,
1
Ja też uznałem objgraph za bardzo przydatny. Możesz robić rzeczy, takie jak objgraph.by_type('dict')zrozumieć, skąd dictpochodzą te wszystkie nieoczekiwane obiekty.
dino,
18

Muppy to (jeszcze jeden) Profiler wykorzystania pamięci dla Pythona. Ten zestaw narzędzi koncentruje się na identyfikacji wycieków pamięci.

Muppy stara się pomóc programistom w wykrywaniu wycieków pamięci Python w aplikacjach. Umożliwia śledzenie zużycia pamięci podczas działania i identyfikację przeciekających obiektów. Dodatkowo dostarczane są narzędzia, które pozwalają zlokalizować źródło nie zwolnionych obiektów.

Serrano
źródło
13

Tworzę profiler pamięci dla Pythona o nazwie memprof:

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

Umożliwia rejestrowanie i wykreślanie zużycia pamięci przez zmienne podczas wykonywania udekorowanych metod. Musisz tylko zaimportować bibliotekę, używając:

from memprof import memprof

I udekoruj swoją metodę za pomocą:

@memprof

To jest przykład tego, jak wyglądają wykresy:

wprowadź opis zdjęcia tutaj

Projekt jest hostowany w GitHub:

https://github.com/jmdana/memprof

jmdana
źródło
3
Jak z tego korzystać? Co to jest a, b, c?
tommy.carstensen
@ tommy.carstensen a, bi csą nazwy zmiennych. Dokumentację można znaleźć na stronie github.com/jmdana/memprof . Jeśli masz jakieś pytania, prosimy o przesłanie problemu w github lub wysłanie wiadomości e-mail na listę mailingową, która znajduje się w dokumentacji.
jmdana
12

Odkryłem, że meliae są znacznie bardziej funkcjonalne niż Heapy lub PySizer. Jeśli zdarzyło Ci się uruchamiać aplikację internetową WSGI, to Dozer to fajne opakowanie oprogramowania pośredniego programu Dowser

Calen Pennington
źródło