Wycieki pamięci Pythona [zamknięte]

zamknięte . To pytanie musi być bardziej skoncentrowane . Obecnie nie przyjmuje odpowiedzi.

chcesz poprawić to pytanie? Update the question so it edytując ten post.

Zamknięte 1 rok temu .

Popraw to pytanie

Mam długo działający skrypt, który, jeśli pozwoli działać wystarczająco długo, pochłonie całą pamięć w moim systemie.

Bez wchodzenia w szczegóły scenariusza, mam dwa pytania:

  1. czy są jakieś "najlepsze praktyki", które pomogą zapobiec wyciekom?
  2. jakie są techniki debugowania wycieków pamięci w Pythonie?
Author: Fragsworth, 2009-09-16

9 answers

Spójrz na ten artykuł: śledzenie wycieków pamięci Pythona

Zauważ również, że moduł garbage collection może mieć ustawione flagi debugowania. Spójrz na funkcję set_debug. Dodatkowo, spójrz na ten kod autorstwa Gnibblera w celu określenia typów obiektów, które zostały utworzone po wywołaniu.

 108
Author: ChristopheD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-02-05 20:07:02

Wypróbowałem większość opcji wymienionych wcześniej, ale okazało się, że ten mały i intuicyjny Pakiet jest najlepszy: pympler

Jest całkiem prosto do śledzenia obiektów, które nie zostały zebrane śmieci, sprawdź ten mały przykład:

Zainstaluj pakiet poprzez pip install pympler

from pympler.tracker import SummaryTracker
tracker = SummaryTracker()

# ... some code you want to investigate ...

tracker.print_diff()

Wyjście pokazuje wszystkie obiekty, które zostały dodane, Plus pamięć, którą zużyły.

Przykładowe wyjście:

                                 types |   # objects |   total size
====================================== | =========== | ============
                                  list |        1095 |    160.78 KB
                                   str |        1093 |     66.33 KB
                                   int |         120 |      2.81 KB
                                  dict |           3 |       840 B
      frame (codename: create_summary) |           1 |       560 B
          frame (codename: print_diff) |           1 |       480 B

Ten pakiet zawiera wiele innych funkcji. Sprawdź dokumentacja pymplera , w szczególności sekcja identyfikująca wycieki pamięci .

 87
Author: linqu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-20 07:38:37

Polecę mem_top narzędzie, które stworzyłem

Pomogło mi rozwiązać podobny problem

Od razu pokazuje listę podejrzanych o wycieki pamięci w programie Pythona

 29
Author: Denis Ryzhkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-03 06:45:56

Moduł Tracemalloc został zintegrowany jako wbudowany Moduł począwszy od Pythona 3.4 i obecnie jest dostępny również dla wcześniejszych wersji Pythona jako biblioteka innej firmy (nie testowałem go jednak).

Ten moduł jest w stanie wypisać dokładne pliki i linie, które przydzieliły najwięcej pamięci. IMHO, ta informacja jest nieskończenie cenniejsza niż liczba przypisanych instancji dla każdego typu (co kończy się dużą ilością krotek 99% czasu, co jest wskazówka, ale w większości przypadków ledwo pomaga).

Zalecam stosowanie tracemalloc w połączeniu z pyrazytem . 9 razy na 10, uruchomienie Top 10 snippetw pyrasite-shell da ci wystarczająco dużo informacji i wskazówek, aby naprawić wyciek w ciągu 10 minut. Jeśli jednak nadal nie możesz znaleźć przyczyny wycieku, powłoka pyrazyt w połączeniu z innymi narzędziami wymienionymi w tym wątku prawdopodobnie da ci więcej wskazówek. Należy również spojrzeć na wszystkie dodatkowych pomocników dostarczanych przez pyrasite (np. przeglądarkę pamięci).

 19
Author: user1527491,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-16 19:40:05

Powinieneś szczególnie spojrzeć na swoje dane globalne lub statyczne (long living data).

Gdy te dane rosną bez ograniczeń, możesz również mieć problemy w Pythonie.

Garbage collector może zbierać tylko dane, które nie są już odwołane. Ale Twoje dane statyczne mogą łączyć elementy danych, które powinny zostać zwolnione.

Innym problemem mogą być cykle pamięci, ale przynajmniej teoretycznie Śmieciarz powinien znaleźć i wyeliminować cykle - przynajmniej tak długo, jak są nie jestem uzależniony od jakichś danych.

Jakie dane długo żyjące są szczególnie kłopotliwe? Dobrze przyjrzyj się wszelkim listom i słownikom-mogą rosnąć bez żadnych ograniczeń. W słownikach możesz nawet nie zauważyć problemów, ponieważ gdy uzyskasz dostęp do dict, Liczba klawiszy w słowniku może nie być dla Ciebie duża widoczność ...

 12
Author: Juergen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-08 06:03:33

Do wykrywania i lokalizowania wycieków pamięci dla długotrwałych procesów, np. w środowiskach produkcyjnych, można teraz użyć stackimpact. Używa tracemalloc pod spodem. Więcej informacji w ten post .

Tutaj wpisz opis obrazka

 7
Author: logix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-01 08:05:51

Jeśli chodzi o najlepsze praktyki, miej oko na funkcje rekurencyjne. W moim przypadku natknąłem się na problemy z rekurencją (gdzie nie było potrzeby). Uproszczony przykład tego, co robiłem:

def my_function():
    # lots of memory intensive operations
    # like operating on images or huge dictionaries and lists
    .....
    my_flag = True
    if my_flag:  # restart the function if a certain flag is true
        my_function()

def main():
    my_function()

Działanie w ten rekurencyjny sposób nie uruchomi zbierania śmieci i nie usunie pozostałości funkcji, więc za każdym razem przez użycie pamięci rośnie i rośnie.

Moim rozwiązaniem było wyciągnięcie rekurencyjnego wywołania z my_function () i mieć main () uchwyt, kiedy go wywołać jeszcze raz. w ten sposób funkcja kończy się naturalnie i oczyszcza się po sobie.

def my_function():
    # lots of memory intensive operations
    # like operating on images or huge dictionaries and lists
    .....
    my_flag = True
    .....
    return my_flag

def main():
    result = my_function()
    if result:
        my_function()
 4
Author: The4thIceman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-03 21:55:14

Nie jestem pewien co do "najlepszych praktyk" dla wycieków pamięci w Pythonie, ale python powinien wyczyścić własną pamięć przez garbage collector. Więc przede wszystkim chciałbym zacząć od sprawdzenia okrągłej listy niektórych krótkich, ponieważ nie zostaną one odebrane przez śmieciarza.

 3
Author: martiert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-16 20:59:56

To nie jest wyczerpująca Rada. Ale najważniejszą rzeczą, o której należy pamiętać pisząc z myślą o unikaniu przyszłych wycieków pamięci (pętli), jest upewnienie się, że wszystko, co akceptuje odniesienie do połączenia zwrotnego, powinno przechowywać to wezwanie jako słabe odniesienie.

 2
Author: Dmitry Rubanovich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-19 20:32:21