Czy Python ma stos / stertę i jak zarządzana jest pamięć?

92

W jaki sposób zarządza się zmiennymi i pamięcią w Pythonie? Czy ma stos i stertę i jaki algorytm jest używany do zarządzania pamięcią? Biorąc pod uwagę tę wiedzę, czy istnieją jakieś zalecenia dotyczące zarządzania pamięcią w przypadku przetwarzania dużej liczby / danych?

Matt Alcock
źródło
1
Czy jest jakiś konkretny problem z zarządzaniem zmienną / pamięcią w Pythonie, z którym masz problem i który nie jest trywialnie wykrywany przez dokumentację Pythona i / lub Google?
Martin James

Odpowiedzi:

112

Jak są zarządzane zmienne i pamięć w Pythonie.

Automagicznie! Nie, naprawdę, po prostu tworzysz obiekt, a maszyna wirtualna Pythona obsługuje potrzebną pamięć i miejsce, w którym powinna zostać umieszczona w układzie pamięci.

Czy ma stos i stertę i jaki algorytm jest używany do zarządzania pamięcią?

Kiedy o CPythontym mowa , używa prywatnej sterty do przechowywania przedmiotów. Z dokumentacji interfejsu API CPython C :

Zarządzanie pamięcią w Pythonie obejmuje prywatną stertę zawierającą wszystkie obiekty i struktury danych Pythona. Zarządzanie tą prywatną stertą jest zapewniane wewnętrznie przez menedżera pamięci Python. Menedżer pamięci Python ma różne komponenty, które zajmują się różnymi aspektami dynamicznego zarządzania pamięcią, takimi jak udostępnianie, segmentacja, wstępna alokacja lub buforowanie.

Odzyskiwanie pamięci jest głównie obsługiwane przez zliczanie referencji . Oznacza to, że maszyna wirtualna języka Python prowadzi wewnętrzny dziennik zawierający informacje o liczbie odwołań do obiektu i automatycznie usuwa go z pamięci, gdy nie ma już odwołań do niego. Ponadto istnieje mechanizm łamania odwołań cyklicznych (których zliczanie referencji nie jest w stanie obsłużyć) poprzez wykrywanie nieosiągalnych „wysp” obiektów, nieco odwrotnie niż tradycyjne algorytmy GC, które próbują znaleźć wszystkie osiągalne obiekty.

UWAGA: pamiętaj, że te informacje sąCPythonszczegółowe. Inne implementacje python, takie jakpypy,iron python,jythoni inni mogą różnić się od siebie i od CPython, jeśli chodzi o ich specyfikę realizacji. Aby lepiej to zrozumieć, pomocne może być zrozumienie, że istnieje różnica między semantyką (językiem) języka Python a podstawową implementacją

Biorąc pod uwagę tę wiedzę, czy istnieją jakieś zalecenia dotyczące zarządzania pamięcią w przypadku przetwarzania dużej liczby / danych?

Teraz nie mogę o tym mówić, ale jestem pewien, że NumPy (najpopularniejsza biblioteka Pythona do chrupania liczb) ma mechanizmy, które z wdziękiem obsługują zużycie pamięci.

Jeśli chcesz dowiedzieć się więcej o elementach wewnętrznych Pythona, zapoznaj się z tymi zasobami:

NlightNFotis
źródło
5
Dobrze z twojej strony, podkreśl różnicę między Pythonem a CPythonem;)
phant0m
1
Zauważ, że zmienne lokalne będą miały rzeczywiste zmienne przechowywane w odpowiedniku ramki stosu.
Marcin
1
Python to nie Java; nie ma maszyny wirtualnej; ma tłumacza. Wskazanie na to może wydawać się pedantyczne, ale są to dwa różne paradygmaty, a różnica ma ważne konsekwencje dla sposobu kompilowania i uruchamiania kodu. stackoverflow.com/questions/441824/…
Apollo2020
49

Python nie ma żadnego takiego.

Python jest językiem i nie określa, jak dokładnie implementacje muszą osiągnąć semantykę zdefiniowaną przez Pythona jako język.

Każda implementacja (CPython, PyPy, IronPython, Stackless , Jython ...) jest darmowa!

W C Pythonie wszystkie obiekty żyją na stercie:

Zarządzanie pamięcią w Pythonie obejmuje prywatną stertę zawierającą wszystkie obiekty i struktury danych Pythona. 1

Maszyna wirtualna CPython jest oparta na stosie:

>>> def g():
    x = 1
    y = 2
    return f(x, y)

>>> import dis
>>> dis.dis(g)
  2           0 LOAD_CONST           1 (1) # Push 1 onto the stack
              3 STORE_FAST           0 (x) # Stores top of stack into local var x

  3           6 LOAD_CONST           2 (2) # Push 2 onto stack
              9 STORE_FAST           1 (y) # Store TOS into local var y

  4          12 LOAD_GLOBAL          0 (f) # Push f onto stack
             15 LOAD_FAST            0 (x) # Push x onto stack
             18 LOAD_FAST            1 (y) # Push y onto stack
             21 CALL_FUNCTION        2     # Execute function with 2 
                                           # f's return value is pushed on stack
             24 RETURN_VALUE               # Return TOS to caller (result of f)

Należy pamiętać, że jest to specyficzne dla CPythona. Stos nie zawiera jednak rzeczywistych wartości, zachowuje odniesienia do tych obiektów.

1 : Źródło

phant0m
źródło