我最近问了一个 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 的引用计数器仍然认为对每个对象的引用都存在,因此永远不会释放内存。您最终在内存中拥有两个对象,而无法访问其中任何一个的数据!My question is: What is the proper way to deal with cyclic references to ensure Perl handles its cleanup properly? How do you make sure Perl doesn't leave any pieces behind when all external references to a self-referential object are eliminated?
最佳答案
Scalar::Util
尤其是 weaken
功能。
The lvalue $ref will be turned into a weak reference. This means that it will not hold a reference count on the object it references. Also when the reference count on that object reaches zero, the reference will be set to undef. This function mutates the lvalue passed as its argument and returns no value.
将您的一个或两个引用设置为“弱”,当 anchor 被破坏时,菊花链将自动解开。
关于perl - 防止 Perl 中的循环引用内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32011106/