编译正则表达式时Perl程序泄漏内存

时间:2017-04-08 00:34:06

标签: regex perl memory-leaks

我有一个程序显示内存泄漏,但我无法跟踪它。我写的测试程序用来证明这个行为很奇怪,我想确保理解为什么。

在示例中有两个数组,一个名为regexLeak,另一个名为noLeak。 noLeak数组只是使用两个简单的正则表达作为基线。 regexLeak数组包含使用字符集的正则表达式。

测试程序获取数组的内容,可能是填充了正则表达式模式,将其传递给编译正则表达式的函数,并放入一个作为参考传回的数组中。

当“test”数组设置为noLeak时,没有泄漏。当“test”数组设置为regexLeak时,会出现明显的内存泄漏。但是,如果regexLeak数组只包含一个元素,则不会发生泄漏。无论哪个元素都无关紧要。将两个元素都放在数组中,然后使用内存在屋顶进行拍摄。

#!/usr/bin/perl

use strict;
use warnings;

my @regexLeak;
my @noLeak;

# Leaks only when both elements are added to @regexLeak
push(@regexLeak,'user = ([a-zA-Z0-9-_.@]+)');
push(@regexLeak,'admin = ([a-zA-Z0-9-_.@]+)');

# No leaks
push(@noLeak, 'simpleRegex');
push(@noLeak, 'anotherSimpleOne');

my @test = @regexLeak;

my $compiled = compileRegex(@test);

while (1) {

    $compiled = compileRegex(@test);
    # print scalar @{$compiled}."\n";
    # select(undef, undef, undef, 0.25);
}

sub compileRegex {
    my (@r) = @_;

    my @compiled;

    foreach my $regex (@r) {
        my $c = qr/$regex/;
        push(@compiled,$c);
    }

    return \@compiled;
}

这部分内容来自展示此问题的制作计划。例如,全局$编译变量。我想把它放在这里,因为通过它们的解释会帮助我理解。这也是一个长期运行的程序,所以泄漏是一个问题。

使用ps -aux观察内存泄漏并查看RSS和VSZ大小。

感谢任何帮助或指导,谢谢!

编辑: 如果您需要任何其他环境信息,请告诉我

  

为x86_64-linux-thread-multi

构建的Perl v5.24.0

1 个答案:

答案 0 :(得分:6)

答案简短:安装

  • v5.16.3v5.18.2(旧版本)
  • 5.25.10(dev-version)
  • v5.24.05.24.1显示正在增长的内存

未经测试的其他版本。

详细结果:

测试了上面的脚本leak.pl,只是将这一行添加到脚本的顶部:

print "version: $^V ($^X) PID: $$\n";

在第二个终端上运行此bash脚本

while :; do
    ps -o pid=,vsz=,rss=,command= | grep 'perl.*[l]eak'
    sleep 0.5
done

结果

plenv 5.16.3

$ plenv local 5.16.3
$ perl leak.pl
version: v5.16.3 (/opt/anyenv/envs/plenv/versions/5.16.3/bin/perl5.16.3) PID: 4922
^C

pspid=,vsz=,rss=,command=

 4922  2437208   3264 perl leak.pl
 4922  2441304   3312 perl leak.pl
 ....
 4922  2441304   3312 perl leak.pl
 # constant

操作系统默认v5.18.2

$ perl leak.pl
version: v5.18.2 (/usr/bin/perl) PID: 5718
#the ps constant
 5718  2455608   3612 perl leak.pl
 5718  2457656   3636 perl leak.pl
 ...
 5718  2457656   3636 perl leak.pl

plenv 5.24.0

$ perl leak.pl
version: v5.24.0 (/opt/anyenv/envs/plenv/versions/5.24.0/bin/perl5.24.0) PID: 6342
# GROWING
 6342  2458172  10672 perl leak.pl
 6342  2495036  40820 perl leak.pl
 6342  2526784  70984 perl leak.pl
 6342  2547268 101492 perl leak.pl
 6342  2579012 132380 perl leak.pl
 6342  2600516 163320 perl leak.pl
 6342  2639432 193636 perl leak.pl
 6342  2669128 223836 perl leak.pl
 6342  2700872 254012 perl leak.pl
 6342  2738760 284400 perl leak.pl
 6342  2768456 314256 perl leak.pl
 6342  2789960 344668 perl leak.pl

plenv 5.24.1

$ perl leak.pl
version: v5.24.1 (/opt/anyenv/envs/plenv/versions/5.24.1/bin/perl5.24.1) PID: 6518
#GROWING
 6518  2466296  23968 perl leak.pl
 6518  2504188  51404 perl leak.pl
 6518  2523644  78616 perl leak.pl
 6518  2560512 105832 perl leak.pl
 6518  2597376 133460 perl leak.pl
 6518  2617856 160496 perl leak.pl
 6518  2643460 187020 perl leak.pl
 6518  2672132 214760 perl leak.pl
 6518  2707972 241532 perl leak.pl
 6518  2743812 269120 perl leak.pl
 6518  2778628 296564 perl leak.pl
 6518  2798084 323252 perl leak.pl
 6518  2825732 350136 perl leak.pl

plenv 5.25.10

$ perl leak.pl
version: v5.25.10 (/opt/anyenv/envs/plenv/versions/5.25.10/bin/perl5.25.10) PID: 6732
# perl adjusted few times the memory - but steady constant
 6732  2445952   3760 perl leak.pl
 6732  2445952   3760 perl leak.pl
 6732  2446976   3772 perl leak.pl
 6732  2448000   3784 perl leak.pl
 6732  2448000   3784 perl leak.pl
 6732  2448000   3784 perl leak.pl
 6732  2448000   3784 perl leak.pl
 6732  2450048   3808 perl leak.pl
 6732  2450048   3812 perl leak.pl
 6732  2450048   3812 perl leak.pl
 6732  2450048   3812 perl leak.pl
 6732  2450048   3812 perl leak.pl
 6732  2450048   3812 perl leak.pl
 ...
 6732  2450048   3812 perl leak.pl