według badania Stackoverflow z 2019 r. język programowania Python uzyskał 73,1% aprobaty wśród programistów. Zajmuje drugie miejsce po Rust i nadal dominuje w naukach o danych i uczeniu maszynowym (ML).
Python jest ulubieńcem programistów. Jest to język wysokiego poziomu znany ze swojej solidności i podstawowej filozofii-prostota nad złożonością. Jednak wydajność aplikacji Python to inna historia. Podobnie jak każda inna aplikacja, ma swój udział w problemach z wydajnością.
przez większość czasu Narzędzia APM, takie jak Retrace, mogą pomóc w rozwiązywaniu problemów z wydajnością aplikacji. Ale co, jeśli Twoja aplikacja w Pythonie działa od czterech godzin, a serwerowi brakuje pamięci? Jest to specyficzny problem związany z zasobami pamięci.
to się nazywa wyciek pamięci. Deweloperzy muszą znaleźć winowajcę. Wtedy właśnie pojawiają się Profilery pamięci Pythona.
zbadajmy dalej.
czym są Profilery pamięci Pythona?
aplikacje profilujące zawsze wiążą się z problemami takimi jak procesor, pamięć itp. Jednak Aplikacje Pythona są podatne na problemy z zarządzaniem pamięcią. Dzieje się tak przede wszystkim dlatego, że Python jest stosowany w aplikacjach Data Science I ML i działa z ogromnymi ilościami danych. Ponadto Python domyślnie opiera się na swoim systemie zarządzania pamięcią, zamiast pozostawiać go użytkownikowi.
ponieważ Kod Pythona działa w kontenerach poprzez rozproszony framework przetwarzania, każdy kontener zawiera stałą ilość pamięci. Jeśli wykonanie kodu przekroczy limit pamięci, kontener zakończy działanie. To jest, gdy rozwój doświadcza błędów pamięci.
jednak nie zawsze tak jest. Istnieją przypadki, w których programiści nie wiedzą, co się dzieje. Może obiekt wisi do odniesienia, kiedy nie powinien być i buduje się z czasem. Gdy osiągnie swój szczyt, pojawiają się problemy z pamięcią.
rozwiązaniem quick-fix jest zwiększenie alokacji pamięci. Nie jest to jednak praktyczne, ponieważ może to prowadzić do marnotrawstwa zasobów. Ponadto może to zagrozić stabilności aplikacji z powodu nieprzewidywalnych skoków pamięci.
dlatego potrzebujemy pomocy Profilerów pamięci Pythona. Celem Python memory profilers jest wykrywanie wycieków pamięci i optymalizacja wykorzystania pamięci w aplikacjach Pythona. Tego typu profilery pamięci Pythona rozumieją wydajność przestrzeni użytego kodu i pakietów.
Top Python Memory Profilers
chociaż Python automatycznie zarządza pamięcią, potrzebuje narzędzi, ponieważ długotrwałe zadania Pythona zużywają dużo pamięci. W większości przypadków zadania te nie zwrócą pamięci do systemu operacyjnego, dopóki proces się nie zakończy, nawet jeśli poprawnie wykona usuwanie śmieci.
oto lista znanych profilerów pamięci Pythona:
Pympler
Jean Brouwers, Ludwig Haehne i Robert Schuppenies zbudowali Pympler w sierpniu 2008 roku. Wprowadzili proces pymplingu, w którym Pympler uzyskuje szczegóły dotyczące wielkości i żywotności obiektów Pythona.
Python memory profiler firmy Pympler analizuje zachowanie pamięci obiektu Python wewnątrz uruchomionej aplikacji. Zapewnia kompletne i samodzielne rozwiązanie do profilowania pamięci w języku Python. Ponadto projektuje możliwe błędy w zachowaniu środowiska uruchomieniowego, takie jak memory bloat i inne „pymples.”
wewnątrz Pymplera znajdują się trzy oddzielne moduły.
- moduł Asizeof dostarcza informacji o rozmiarze obiektu Python.
- moduł muppy służy do monitorowania on-line aplikacji Pythona.
- moduł Class Tracker umożliwia analizę off-line żywotności wybranych obiektów Pythona.
najpierw użyjmy asizeof do zbadania, ile pamięci zużywają niektóre obiekty Pythona.
>>> from pympler import asizeof
>>> obj =
>>> asizeof.asizeof(obj)
>>> print (asizeof.asized(obj, detail=1).format())
size=192 flat=48
(6, 4) size=64 flat=32
'i’ size=32 flat=32
3 size=16 flat=16
2 size=16 flat=16
1 size=16 flat=16
Po Drugie, zaimplementujmy moduł muppy:
>>>>>>> allobjects = muppy.get_objects()
>>> len(wszystkie obiekty)
>>> z pympler zaimportować cv
>>> Ja = cv.uogólnij (wszystkie obiekty)
types | | # objects | | total size |
========================== | | =========== | | ============ |
str | | 13262 | | 1.01 MB |
dict | | 2120 | | 659.99 KB |
code | | 3362 | | 343.73 KB |
list | | 2587 | | 247.46 KB |
type | | 639 | | 242.61 KB |
tuple | | 2069 | | 58.83 KB |
set | | 86 | | 44.57 KB |
wrapper_descriptor | | 1247 | | 43.84 KB |
builtin_function_or_method | | 1014 | | 35.65 KB |
method_descriptor | | 937 | | 32.94 KB |
abc.ABCMeta | | 66 | | 32.38 KB |
weakref | | 818 | | 28.76 KB |
int | | 1612 | | 24.72 KB |
getset_descriptor | | 555 | | 17.34 KB |
frozenset | | 90 | | 16.87 KB |
tutaj możesz wyświetlić wszystkie obiekty Pythona w stercie za pomocą modułu muppy. Możesz wywołać inne podsumowanie i porównać je, aby sprawdzić, czy niektóre tablice mają wycieki pamięci. Dowiedz się więcej o module muppy tutaj.
trzecim modułem W Pympler profiler jest Class Tracker. Śledzi żywotność obiektów określonych klas. Thus, it provides insight into instantiation patterns and helps developers understand how specific objects contribute to the memory footprint in the long run.
>>> tr = classtracker.ClassTracker()
>>> tr.track_class(Document)
>>> tr.create_snapshot(description=’Snapshot 1′)
>>> doc = create_document()
>>> tr.create_snapshot(description=’Snapshot 2′)
>>> tr.stats.print_summary ()
— podsumowanie ———————-
Migawka 1 aktywna 0 b średnia pct
Migawka 2 aktywna 0 b średnia pct
—————————
aby dowiedzieć się więcej o Class Tracker, kliknij tutaj.
Guppy3
Guppy3 (znany również jako Heapy) jest środowiskiem programistycznym Pythona i zestawem narzędzi do analizy sterty. Jest to pakiet, który zawiera następujące podpakiety:
- etc – jest to moduł wsparcia, który posiada moduł protokołu Glue.
- gsl – pakiet zawierający implementację języka specyfikacji Guppy. Tworzy dokumenty i testy ze wspólnego źródła.
- heapy – zestaw narzędzi do analizy sterty dostarcza informacji o obiekcie i wyświetla te informacje.
- zestawy – zawiera zestawy bitów i nodesetów.
Guppy 3 jest forkiem Guppy-PE i został zbudowany przez Sverkera Nilssona dla Pythona 2.
Uwaga: używanie tego profilera pamięci Pythona wymaga Pythona 3.5, 3.6, 3.7 lub 3.8. Ten pakiet działa tylko dla CPython. Dlatego PyPy i inne implementacje kompilatorów Pythona nie są obsługiwane. Ponadto, aby korzystać z przeglądarki graficznej, potrzebuje Tkinter. Ponadto gwintowanie musi być dostępne podczas korzystania ze zdalnego monitora.
oto jak wykorzystać ten Python memory profiler. Możesz zrobić migawkę sterty przed i po krytycznym procesie. Następnie porównaj całkowitą pamięć i wskaż możliwe skoki pamięci związane ze wspólnymi obiektami.
>>> from guppy import hpy
>>> h=hpy()
>>> h.heap()
Partition of a set of 34090 objects. Total size = 2366226 bytes.
Index | Count | % | Size | % | Cumulative | % | Kind (class / dict of class) |
0 | 10279 | 30 | 666873 | 28 | 666873 | 28 | str |
1 | 4697 | 14 | 259576 | 11 | 926449 | 39 | bytes |
2 | 2413 | 7 | 251684 | 11 | 1178133 | 50 | types.CodeType |
3 | 6825 | 20 | 238084 | 10 | 1416217 | 60 | tuple |
4 | 448 | 1 | 174868 | 7 | 1591085 | 67 | type |
5 | 2208 | 6 | 150144 | 6 | 1741229 | 74 | function |
6 | 448 | 1 | 130964 | 6 | 1872193 | 79 | dict of type |
7 | 94 | 0 | 83532 | 4 | 1955725 | 83 | dict of module |
8 | 242 | 1 | 56524 | 2 | 2012249 | 85 | dict (no owner) |
9 | 1133 | 3 | 40788 | 2 | 2053037 | 87 | types.WrapperDescriptorType |
<118 more rows. Type e.g. ‘_.more’ to view.>
Memory Profiler
Memory Profiler is a pure Python module that uses the psutil module. Monitoruje zużycie pamięci przez proces Zadań Pythona. Ponadto wykonuje analizę liniową zużycia pamięci przez aplikację.
tryb użycia pamięci line-by-line działa tak samo jak line_profiler.
- dekoruje funkcję, którą chcesz profilować za pomocą funkcji @profile.
- możesz uruchomić skrypt za pomocą specjalnego skryptu. Na przykład użyj konkretnych argumentów do interpretera Pythona.
w poniższym przykładzie, miejmy prostą funkcję o nazwie my_func. Ta funkcja tworzy listę z określonym zakresem.
@profile
def my_func():
a=
for i in range(1000):
a.append(i)
my_func()
This outputs:
Line # | Mem Usage | Increment | Line Contents |
1 | 13.859 MiB | 13.859 MiB | @profile |
2 | def my_func(): | ||
3 | 13.859 MiB | 0.000 MiB | a= |
4 | 13.859 MiB | 0.000 MiB | dla i w zakresie(1000): |
5 | 13,859 MiB | 0,000 MiB | a.append(i) |
Pierwsza kolumna to numer linii kodu profilowanego. Użycie Mem to użycie pamięci interpretera Pythona po każdym wykonaniu kodu. Trzecia kolumna (przyrost) reprezentuje różnicę w pamięci bieżącej linii do ostatniej. Ostatnia kolumna (zawartość wiersza) wyświetla profilowane kody.
To see how this Python memory profiler works, let’s change the range value to 1000000 in the function above and execute it. Here is the output:
Line # | Mem usage | Increment | Line Contents |
1 | 13.844 MiB | 13.844 MiB | @profile |
2 | def my_func(): | ||
3 | 13.844 MiB | 0.000 MiB | a= |
4 | 33.387 MiB | 0.016 MiB | dla i w zakresie(1000000): |
5 | 33,387 MiB | 0,293 MiB | a.append(i) |
linie 4 i 5 pokazują wzrost zużycia pamięci, udowadniając, że ten profiler wykonuje analizę zużycia pamięci linia po linii.
Fil
Fil profiler jest open-source Python memory profiler. Nadaje się do przetwarzania danych i Zastosowań Informatyki naukowej. Obecnie jest nadal w fazie rozwoju i działa tylko na Linuksie i macOS.
większość analityków danych i programistów Pythona ma problemy z pamięcią w pythonowym potoku danych. Gdy zużywa zbyt dużo pamięci, trudno jest wskazać, gdzie dokładnie zmierza cała pamięć.
na przykład przytoczmy dwa scenariusze:
Serwery
ponieważ serwery działają non-stop, wycieki pamięci są często przyczyną awarii wydajności. Deweloperzy zaniedbują małe ilości wycieku pamięci, ponieważ większość serwerów przetwarza małe ilości danych naraz. Mogą one jednak sumować się do dziesiątek tysięcy połączeń. W rezultacie może to z czasem spowodować poważne problemy produkcyjne.
potoki danych
podczas przetwarzania dużych fragmentów danych skoki zużycia pamięci powodują ogromne zagrożenia dla potoków danych. Na przykład, jeśli Twoja aplikacja używa 1 GB PAMIĘCI RAM przez dłuższy czas, a następnie nagle potrzebuje 16 GB PAMIĘCI RAM. Istnieje wielka potrzeba zidentyfikowania, co powoduje nagłe skoki pamięci.
To jest główny cel Fil―diagnozowanie skoków zużycia pamięci, niezależnie od ilości przetwarzanych danych. Wskazuje, gdzie dokładnie jest szczytowe zużycie pamięci i jaki kod jest odpowiedzialny za ten skok.
chociaż istnieją już Profilery pamięci Pythona, które mierzą zużycie pamięci, ma on ograniczenia. Jednym z nich jest przetwarzanie dużych ilości danych-wsadowe. Aplikacje Python to głównie aplikacje do przetwarzania wsadowego, w którym stale odczytują dane, przetwarzają je i generują wynik.
na ten problem odpowiada nasz następny profiler.
Blackfire
w przypadku bardzo dynamicznego języka, takiego jak Python, większość programistów doświadcza problemów z pamięcią podczas wdrażania. Prowadzi to do nieporozumień co do tego, co dzieje się z wykorzystaniem pamięci. Programiści zwykle wykonują optymalizacje, ale nie mają odpowiednich narzędzi do użycia.
Blackfire jest zastrzeżonym profilerem pamięci Pythona (może pierwszym. Używa menedżera pamięci Pythona do śledzenia każdego bloku pamięci przydzielonego przez Pythona, w tym rozszerzeń C. Blackfire jest nowością w tej dziedzinie i ma na celu rozwiązanie problemów związanych z wyciekami pamięci, takich jak:
- duże obiekty w pamięci, które nie są zwolnione
- cykle referencyjne
- nieprawidłowe liczenie referencji w rozszerzeniach C powodujące wycieki pamięci
- nagłe skoki pamięci
w tych przypadkach użycia, Blackfire zapewnia użytkownikom, że ma bardzo ograniczony narzut i nie ma wpływu na użytkowników końcowych, ponieważ mierzy zużycie pamięci aplikacji Python na poziomie wywołania funkcji.
Blackfire Python memory profiler używa API PYMEM_SETALLOCATOR do śledzenia alokacji pamięci, takich jak tracemalloc. Obecnie Blackfire obsługuje Pythona w wersji 3.5 i nowszej. Możesz odwiedzić jego stronę, aby dowiedzieć się więcej.
Profilowanie z Retrace
Jeśli pracujesz z Pythonem, w jakiś sposób doświadczasz, że nie zwalnia on natychmiast pamięci z powrotem do systemu operacyjnego. Dlatego uruchamiasz go w oddzielnym procesie, aby upewnić się, że pamięć zostanie zwolniona po wykonaniu fragmentu kodu. Odbywa się to za pomocą użytecznego podejścia zwanego „małym przypadkiem testowym.”Ten proces pozwala na uruchomienie tylko danego kodu wycieku pamięci.
w przypadku dużych ilości danych należy użyć podzbioru losowo pobranych danych. Ponadto uruchamiaj zadania wymagające dużej pamięci w oddzielnych procesach i używaj debugerów do dodawania odniesień do obiektów. Należy jednak wziąć pod uwagę, że użycie debugera punktu przerwania, takiego jak pdb, pozwala, aby wszelkie obiekty utworzone i odwołane ręcznie z debugera pozostały w profilu pamięci. Spowoduje to fałszywe poczucie wycieku pamięci, ponieważ obiekty nie są uwalniane na czas. Ponadto rozważ sprawdzenie pakietów, które mogą być nieszczelne. Istnieją Biblioteki Pythona, które potencjalnie mogą mieć wycieki pamięci.
już wiesz, jak działają Profilery pamięci Pythona i typowe problemy z pamięcią w Pythonie. Ale narzędzia takie jak Retrace ze scentralizowanym rejestrowaniem, śledzenie błędów i profilowanie kodu mogą pomóc w diagnozowaniu problemów Pythona na większą skalę. Retrace z Stackify pomoże Ci radzić sobie z wszelkiego rodzaju pułapkami wydajności i utrzymać poprawne działanie kodu.
rozpocznij 14-dniowy darmowy okres próbny Retrace już dziś!