繁体   English   中英

Perl map / grep内存泄漏

[英]Perl map/grep memory leak

我一直在研究工作中的perl项目,并遇到了一个奇怪的内存泄漏。 我把我的问题的根源归结为一个人为的例子:

#!/usr/bin/perl
use strict;
use warnings;

# takes: an array reference
# returns: 1
sub g {
    my ($a) = @_;
    return 1; 
}

# takes: nothing
# returns: the result of applying g on an array reference
sub f {
    my @a = ('a') x 131072; # allocate roughly a megabyte 
    return g(\@a); 
}

# causes a leak:
#map { f($_) } (1..100000); 

# loop equivalent to map, no leak:
#my @b;
#for my $i (1..100000) {
#    push @b, f($_);
#}

# causes a leak:
#grep { f($_) } (1..100000);

# loop equivalent to grep, no leak:
#my @b;
#for my $i (1..100000) {
#    push @b, $i if f($_);
#}

取消注释4个代码块中的1个(在子例程下面)并在监视其内存使用情况时运行脚本。 在我的机器上,使用grep或map的代码似乎会导致内存泄漏,而“循环等效”则不会。 我的perl版本是v5.10.1,我正在运行Ubuntu。

我相信这可能是perl中的一个错误,但我不想在没有关于可能的原因的另一个意见的情况下跳到一个激烈的结论。 任何人都可以解释这种行为是否正确?

谢谢

我不知道这是否是内存泄漏。 如果我降低循环的最高值(例如,从100000到100),我可以重复使用map / grep表达式而不会丢失内存。

相反,当涉及内存管理时, mapgrep似乎更有可能是原子操作,perl在这些操作的中间不执行其垃圾收集。

Perl 5.12.0(和5.8.9)在这些表达式上确实看起来更强大(但它们似乎也更慢)。

它确实是。 但为了证明这一点,你必须将while(1){}置于可疑表达式之外 - 在perl中,曾经获得的内存永远不会返回到OS(但可以由perl本身重用)。 我用的是代码

while(1){grep {f($ _)}(1..100000)}

5.8.8以下,它的大小不断增加 - 所以,这是一个泄漏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM