perl – 递归调用另一个匿名sub是否安全?
发布时间:2020-12-16 06:27:39 所属栏目:大数据 来源:网络整理
导读:我想使用匿名子而不是命名子的原因是因为我想在Mason子组件( http://www.masonbook.com/book/chapter-2.mhtml#TOC-ANCHOR-7)中定义这些子组件,这些组件在命名子组件中表现不佳. 例如.如果我以这种方式编写代码: my ($first,$second);$first = sub { my $val
我想使用匿名子而不是命名子的原因是因为我想在Mason子组件(
http://www.masonbook.com/book/chapter-2.mhtml#TOC-ANCHOR-7)中定义这些子组件,这些组件在命名子组件中表现不佳.
例如.如果我以这种方式编写代码: my ($first,$second); $first = sub { my $val = shift; print "val: $val"; $second->($val); }; $second = sub { my $val = shift; if (0 < $val) { $val = $val - 1; $first->($val); } }; $first->(10); 这种方法中是否存在任何隐藏的陷阱(例如内存泄漏等)? 正如@Schwern所解释的那样,Perl不会释放这些子的内存,因为它们之间存在循环引用. 但更具体地说,内存分配是否会线性增长,因为$val会增加,或者它不依赖于调用堆栈深度?因为我可以将这些潜艇放在梅森<%once>块,在这种情况下,这些子只会被初始化一次. 解决方法
我唯一能想到的是子程序永远不会被释放,即使$first和$second超出范围. $first的代码是指$second,$second的代码是指$first.这是一个循环数据结构,Perl的内存分配无法解除分配.
$perl -wlE 'for (1..10_000) { my($first,$second); $first = sub {}; $second = sub {} } say "Done"; sleep 1000' $perl -wlE 'for (1..10_000) { my($first,$second); $first = sub { $second->() }; $second = sub { $first->() } } say "Done"; sleep 1000' 第一个Perl进程在循环后使用1912K,第二个使用10320K.无论创建多少CV,第一个都不会增长,第二个会. 要解决这个问题,你必须通过取消定义$first或$second来打破这个圈子.第三个在循环内调用undef $,它的内存不会增长. $perl -wlE 'for (1..100_000) { my($first,$second); $first = sub { $second->() }; $second = sub { $first->() }; undef $first; } say "Done"; sleep 1000' (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |