Недавно я спросил question о перезаписи объектов и управления памятью в Perl. Один из ответов, которые я получил, уведомил меня, что у меня может возникнуть проблема с script, который я недавно написал.
У меня есть script с некоторыми очень сложными структурами данных, которые имеют много отношений parent->child / child->parent
. Это также означает, что существует много объектов, которые имеют циклические ссылки. В соответствии с этим ответом циклические ссылки могут "обмануть" механизм подсчета ссылок Perl и вызвать утечку памяти, если они не обрабатываются должным образом.
Пример циклической ссылки:
+-----------------------------------------------------+
| |
+-->+============+ +==========+ |
[ Reference ----->[ Blessed ] |
$parent -->+============+ [ Hash ] |
[ ] +==========+ |
[ children --->[ Array ] |
[ ] [ ] |
+==========+ [ 0: ---------+ |
[ ] | |
+==========+ | |
| |
+--------------------------------------------------+ |
| |
+-->+============+ +==========+ |
[ Reference ----->[ Blessed ] |
$child --->+============+ [ Hash ] |
[ ] |
[ parent: ----------------------+
[ ]
+==========+
(Отказ от ответственности - это не мое эпическое произведение - спасибо @Ikegami за эту сладкую диаграмму ASCII!)
Проблема: Каждый объект имеет ссылку на другую., это означает, что после того, как $parent
и $child
исчезнут из области видимости, счетчик ссылок Perl все еще считает, что ссылка на каждый объект существует, поэтому память никогда не освобождается. Вы завершаете работу с двумя объектами в памяти, чтобы не получить доступ к данным ни одного из них!
Мой вопрос: Каков правильный способ обработки циклических ссылок, чтобы Perl правильно обрабатывал его очистку? Как вы убеждаетесь, что Perl не оставляет никаких деталей, когда устраняются все внешние ссылки на самореферентный объект?