防止Perl中的循环参考内存泄漏 [英] Preventing cyclic reference memory leaks in Perl

查看:104
本文介绍了防止Perl中的循环参考内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I recently asked a question about overwriting objects and memory management in Perl. One of the answers I received notified me that I may have an issue with a script I recently wrote.

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

I have a script with some very complex data structures that have many parent->child / child->parent relationships. This also means that there are many objects that have cyclic references. According to this answer, cyclic references can "trick" Perl's reference counting mechanism and cause memory leaks if they are not dealt with properly.

循环引用的示例:

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

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

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

Problem: Each object has a reference to the other . . . this means that once $parent and $child go out of scope, Perl's reference counter still thinks that a reference to each object exists so the memory is never freed. You wind up with two objects in memory with no way to access the data of either of them!

我的问题是:处理循环引用以确保Perl正确处理其清理的正确方法是什么?当消除对自引用对象的所有外部引用时,如何确保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函数.

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

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.

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

Set one - or both - of your references as "weak" and the daisy chain will unravel automagically when the anchors are destructed.

这篇关于防止Perl中的循环参考内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆