perl - 防止 Perl 中的循环引用内存泄漏

标签 perl oop memory-leaks cyclic-reference

我最近问了一个 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/

相关文章:

perl - 在@INC 中找不到 DBD/Oracle.pm

oop - 元表在 Lua (5.2) 中为 OOP 服务的目的是什么?

haskell - 无法强制尾递归严格

php - 关于 PHP 中 OOP 的使用,这是正确的吗?

java - 代码效率、调试、对象方法、数组

c -/usr/lib/dyld 中使用 Valgrind 导致内存泄漏

java - 资源警告java

perl - Perl 中的逗号在所有上下文中都是关联的吗?

Perl 高效代码

perl - my 和 our 之间的区别? (在同一个文件中声明)