防止Perl中的循环参考内存泄漏

1992年

我最近问了一个有关在Perl中覆盖对象和内存管理问题我收到的答案之一通知我,我最近编写的脚本可能有问题。

我有一个脚本,其中包含一些具有许多parent->child / child->parent关系的非常复杂的数据结构这也意味着有许多具有循环引用的对象。根据这个答案,循环引用会“欺骗” Perl的引用计数机制,如果处理不当,则会导致内存泄漏。


循环引用的示例:

       +-----------------------------------------------------+
       |                                                     |
       +-->+============+    +==========+                    |
           [ Reference ----->[ Blessed  ]                    |
$parent -->+============+    [ Hash     ]                    |
                             [          ]   +==========+     |
                             [ children --->[ Array    ]     |
                             [          ]   [          ]     |
                             +==========+   [ 0: ---------+  |
                                            [          ]  |  |
                                            +==========+  |  |
                                                          |  |
       +--------------------------------------------------+  |
       |                                                     |
       +-->+============+    +==========+                    |
           [ Reference ----->[ Blessed  ]                    |
$child --->+============+    [ Hash     ]                    |
                             [          ]                    |
                             [ parent: ----------------------+
                             [          ]
                             +==========+

免责声明-这不是我的史诗般的艺术品-感谢@Ikegami提供的这张可爱的ASCII图!

问题:每个对象都有对另一个对象的引用。这意味着,一旦$parent$child去的范围时,Perl的引用计数器仍然认为每个对象的引用存在,所以内存永远不会被释放。您最终在内存中拥有两个对象,而无法访问其中任何一个的数据!


我的问题是:处理循环引用以确保Perl正确处理其清理的正确方法是什么?当消除对自引用对象的所有外部引用时,如何确保Perl不会留下任何残缺?

清醒

Scalar::Util特别是weaken功能。

左值$ ref将变为弱引用。这意味着它将不保留对其引用的对象的引用计数。同样,当该对象的引用计数达到零时,引用将设置为undef。此函数使作为参数传递的左值发生突变,并且不返回任何值。

将您的一个或两个引用都设置为“弱”,并且当锚点被破坏时,菊花链会自动解开。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章