Zanurkuj w Pythonie/Tworzenie instancji klasy: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Sqrll (dyskusja | edycje)
Sqrll (dyskusja | edycje)
Linia 36:
... leakmem() #(2)
 
# Za każdym razem, gdy funkcja <code>leakmem</code> jest wywoływana, zostaje utworzona instancja klasy <code>FileInfo</code>, a ta zostaje przypisana do zmiennej <code>f</code>, która jest lokalną zmienną wewnątrz funkcji. Funkcja ta kończy się bez jakiegokolwiek wyraźnego zwolnienia pamięci zajmowanej przez zmienną <code>f</code>, a więc spodziewalibyśmy się wycieku pamięci, lecz tak nie będzie. Kiedy funkcja się kończy, lokalna zmienna <code>f</code> wychodzi poza swój zakreszasięg. W tym miejscu nie ma więcej żadnych referencji do nowej instancji <code>FileInfo</code>, ponieważ nigdzie nie przypisywaliśmy jej do czegoś innego niż <code>f</code>), tak więc Python zniszczy instancję za nas.
# Niezależnie od tego, jak wiele razy wywołamy funkcję <code>leakmem</code>, nigdy nie otrzymamynastąpi wyciekuwyciek pamięci, ponieważ za każdym razem kiedy to zrobimy Python będzie niszczył nowo utworzony obiekt przed wyjściem z funkcji <code>leakmem</code>.
}}
 
Technicznym terminem tego sposobu odśmiecania pamięci jest "[[w:Reference counting|zliczanie odwołań]]". Python przechowuje listę referencji do każdej utworzonej instancji. W powyższym przykładzie, mamy tylko jedną referencję do instancji <code>FileInfo</code> -- zmienną <code>f</code>. Kiedy funkcja się kończy, zmienna <code>f</code> wychodzi poza zakreszsięg, więc licznik odwołań zmniejsza się do <code>0</code> i Python niszczy tę instancję automatycznie.
 
W poprzednich wersjach Pythona występowały sytuacje, gdy zliczanie odwołań zawodziło i Python nie mógł wyczyścić po nas pamięci. Jeśli tworzyłeś dwie instancje, które odwoływały się do siebie nawzajem (np. instancja listy dwukierunkowej (ang. ''double linked list''), w których każdy węzeł wskazuje na poprzedni i następny znajdujący się w liście), żadna instancja nie była niszczona automatycznie, ponieważ Python uważał (poprawnie), że ciągle mamy referencję do każdej instancji. Od Pythona 2.0 mamy dodatkowy sposób odśmiecania pamięci nazywany po ang. [[w:Garbage collection#Mark and Sweep|''mark-and-sweep'']] (oznacz i zamiataj), dzięki któremu w sprytny sposób Python odnajduje różne wirtualne blokady i poprawnie czyści cykliczne odwołania.