Perl осуществляет управление памятью автоматически: переменные уничтожаются, когда на них не остаётся ссылок (reference counting). Сборщик мусора в Perl не использует типичный tracing GC, а полагается на подсчёт ссылок.
Преимущества:
free(), как в C).Недостатки и подводные камни:
my $a = {}; my $b = {}; $a->{b} = $b; $b->{a} = $a; # Обе переменные не освобождены при очистке, perl не может их удалить
Для решения подобных проблем используют модуль Scalar::Util::weaken, который позволяет "ослабить" ссылку:
use Scalar::Util 'weaken'; my $a = {}; my $b = {}; $a->{b} = $b; weaken($b->{a} = $a);
Ликвидируются ли любые объекты Perl при удалении на них всех явных переменных, даже если внутри есть ссылки между ними?
Ответ: Нет! Если объекты ссылаются друг на друга (создают цикл), Perl их не удалит — понадобится вручную разорвать цикл или ослабить связь через Scalar::Util::weaken.
История
При разработке долговременного демона, работающего с большим числом соединений, программисты не заметили циклическую ссылку между объектом IoHandle и связанным обработчиком события. Через несколько часов работы память вырастала экспоненциально — только анализ с помощью Devel::Leak выявил проблему.
История
В ETL-процессе парсинга больших файлов накопление миллионов временных элементов хэша приводило к "зависанию" процесса даже после завершения цикла. Случилось потому, что один из элементов хранил вложенную ссылку на родителя (для трёхуровневых связей) и не происходило освобождение памяти. Частичная реструктуризация схемы помогла избежать утечки.
История
Программисты использовали замыкания в MapReduce-движке, сохраняя копии контекста в анонимных подпрограммах. Эти подпрограммы «вытекали» — память не освобождали даже после окончания работы batch-задачи, так как контекст содержал ссылки на самих себя. Добавили явный
undefдля корректного уничтожения.