sri*_*eak 14 perl garbage-collection circular-reference
与Java不同,Perl使用引用计数进行垃圾收集.我曾尝试搜索一些以前的问题,这些问题涉及C++ RAII和智能指针以及Java GC,但还没有理解Perl如何处理循环引用问题.
任何人都可以解释Perl的垃圾收集器如何处理循环引用?有没有办法回收程序不再使用的循环引用内存,或者Perl是否完全忽略了这个问题?
Max*_*ert 13
根据我的Programming Perl 3rd ed的副本.在退出时,Perl 5会进行"昂贵的标记和扫描"来回收循环引用.您将希望尽可能避免循环引用,否则在程序退出之前不会回收它们.
Perl 5通过Scalar :: Utils模块提供弱引用.
Perl 6将转移到可插入垃圾收集方案(好吧,底层VM将有多个垃圾收集选项,这些选项的行为可能对Perl产生影响).也就是说,您可以在各种垃圾收集器之间进行选择,也可以实现自己的垃圾收集器.想要一个复制收藏家?当然.想要一个着色收藏家?你说对了.标记/扫描,压缩等?为什么不?
小智 5
简单的回答是Perl 5也不会自动处理循环引用。除非您在代码中采取明确的措施,否则在创建它们的线程死亡之前,任何包含循环引用的数据结构都不会被回收。这被认为是一种可接受的折衷,因为它避免了运行时垃圾收集的需要,这会减慢执行速度。
如果您的代码使用循环引用创建数据结构(即,其节点包含指向根节点的引用的树),您将需要使用 Scalar::Util 模块来“弱化”指向根节点的引用。这些弱引用不会增加它们指向的任何引用计数,因此当最后一个外部引用消失时,整个数据结构将自动释放。
例子:
use Scalar::Util qw(weaken);
...
my $new_node = { content => $content, root => $root_node };
weaken $new_node->{root};
push @{$root_node->{children}}, $new_node;
Run Code Online (Sandbox Code Playgroud)
如果每当向数据结构添加新节点时都使用这样的代码,那么实际计算的对根的唯一引用是来自结构外部的引用。这正是您想要的。然后,只要对它的最后一个外部引用消失,就会回收根,以及递归它的所有子项。
| 归档时间: |
|
| 查看次数: |
9548 次 |
| 最近记录: |