我有一个脚本具有一些非常复杂的数据结构,这些数据结构具有很多父 – 子(child)和/或父 – 母关系.这也意味着有许多具有循环引用的对象.根据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
具体是削弱功能.
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.
将您的引用中的一个或两个设置为“弱”,并且当锚被破坏时,菊花链将自动解开.