我最近问了一个
question
关于用Perl重写对象和内存管理。我收到的一个回答告诉我,我可能对我最近写的剧本有问题。
我有一个脚本,其中包含一些非常复杂的数据结构
parent->child / child->parent
关系。这也意味着有许多对象具有循环引用。根据
this answer
,循环引用可以“欺骗”Perl的引用计数机制,如果处理不当,会导致内存泄漏。
循环引用示例:
+-----------------------------------------------------+
| |
+-->+============+ +==========+ |
[ Reference ----->[ Blessed ] |
$parent -->+============+ [ Hash ] |
[ ] +==========+ |
[ children --->[ Array ] |
[ ] [ ] |
+==========+ [ 0: ---------+ |
[ ] | |
+==========+ | |
| |
+--------------------------------------------------+ |
| |
+-->+============+ +==========+ |
[ Reference ----->[ Blessed ] |
$child --->+============+ [ Hash ] |
[ ] |
[ parent: ----------------------+
[ ]
+==========+
(
免责声明——这不是我的史诗作品——感谢@Ikegami提供的这张漂亮的ASCII图!
)
问题:
每个对象都有对另一个对象的引用…这意味着一旦
$parent
和
$child
超出范围,Perl的引用计数器仍然认为存在对每个对象的引用,因此内存永远不会被释放。最后,内存中有两个对象,无法访问其中任何一个对象的数据!
我的问题是:
处理循环引用以确保Perl正确处理其清理的正确方法是什么?当消除了对自引用对象的所有外部引用时,如何确保Perl不会留下任何片段?