Perl automatycznie zarządza pamięcią: zmienne są niszczone, gdy nie ma do nich już odniesień (liczenie odniesień).
Zalety:
free(), jak w C).Wady i pułapki:
my $a = {}; my $b = {}; $a->{b} = $b; $b->{a} = $a; # Obie zmienne nie są zwalniane podczas czyszczenia, perl nie może ich usunąć
Aby rozwiązać podobne problemy, używa się modułu Scalar::Util::weaken, który pozwala "osłabić" odniesienie:
use Scalar::Util 'weaken'; my $a = {}; my $b = {}; $a->{b} = $b; weaken($b->{a} = $a);
Czy wszelkie obiekty Perl są usuwane po usunięciu wszystkich jawnych zmiennych do nich, nawet jeśli wewnątrz znajdują się odniesienia między nimi?
Odpowiedź: Nie! Jeśli obiekty odnoszą się do siebie nawzajem (tworzą cykl), Perl ich nie usunie — trzeba ręcznie przerwać cykl lub osłabić powiązanie przez Scalar::Util::weaken.
Historia
Podczas tworzenia długoterminowego demona, obsługującego dużą liczbę połączeń, programiści nie zauważyli cyklicznego odniesienia między obiektem IoHandle a związanym z nim wyzwalaczem zdarzeń. Po kilku godzinach pracy pamięć rosła w sposób wykładniczy — tylko analiza przy pomocy Devel::Leak ujawniła problem.
Historia
W procesie ETL parsowania dużych plików, gromadzenie milionów tymczasowych elementów hasha prowadziło do "zawieszenia" procesu nawet po zakończeniu cyklu. Stało się to dlatego, że jeden z elementów przechowywał zagnieżdżone odniesienie do rodzica (dla trójpoziomowych powiązań) i nie następowało zwalnianie pamięci. Częściowa restrukturyzacja schematu pomogła uniknąć wycieku.
Historia
Programiści użyli zamknięć w silniku MapReduce, zachowując kopie kontekstu w anonimowych podprogramach. Te podprogramy „wypływały” — pamięć nie była zwalniana nawet po zakończeniu pracy zadania wsadowego, ponieważ kontekst zawierał odniesienia do samych siebie. Dodano jawny
undefdla poprawnego zniszczenia.