Perl map/grep内存泄漏

Jam*_*son 6 perl grep memory-leaks map

我一直在研究工作中的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($_);
#}
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢

mob*_*mob 2

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

map相反,当涉及到内存管理时,和似乎更可能grep是原子操作,perl 不会在这些操作中间执行垃圾收集。

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