我最近问了一个question https://stackoverflow.com/questions/31971633/perl-memory-management-when-overwriting-objects关于 Perl 中的覆盖对象和内存管理。我收到的答案之一通知我,我最近编写的脚本可能有问题。
我有一个脚本,其中包含一些非常复杂的数据结构,其中有很多parent->child / child->parent
关系。这也意味着有许多对象具有循环引用。根据这个答案 https://stackoverflow.com/questions/31971633/perl-memory-management-when-overwriting-objects/31974608#31974608、循环引用如果处理不当,会“欺骗”Perl的引用计数机制,导致内存泄漏。
循环引用的示例:
+-----------------------------------------------------+
| |
+-->+============+ +==========+ |
[ Reference ----->[ Blessed ] |
$parent -->+============+ [ Hash ] |
[ ] +==========+ |
[ children --->[ Array ] |
[ ] [ ] |
+==========+ [ 0: ---------+ |
[ ] | |
+==========+ | |
| |
+--------------------------------------------------+ |
| |
+-->+============+ +==========+ |
[ Reference ----->[ Blessed ] |
$child --->+============+ [ Hash ] |
[ ] |
[ parent: ----------------------+
[ ]
+==========+
(免责声明——这不是我的史诗般的艺术作品——感谢@Ikegami 这个可爱的 ASCII 图!)
Problem:每个对象都有对另一个对象的引用。 。 。这意味着一旦$parent
and $child
超出范围,Perl 的引用计数器仍然认为对每个对象的引用都存在,因此内存永远不会被释放。您最终会在内存中得到两个对象,而无法访问其中任何一个的数据!
我的问题是:处理循环引用以确保 Perl 正确处理其清理的正确方法是什么?当对自引用对象的所有外部引用都被消除时,如何确保 Perl 不会留下任何片段?
Scalar::Util http://search.cpan.org/perldoc?Scalar::Util#weaken特别是weaken
功能。
左值 $ref 将变成弱引用。这意味着它不会保留其引用的对象的引用计数。此外,当该对象的引用计数达到零时,该引用将被设置为 undef。该函数会改变作为其参数传递的左值,并且不返回任何值。
将一个或两个参考设置为“弱”,当锚被破坏时,菊花链将自动解开。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)