2013-04-30 31 views
2

我最近一直在对一块特别粗糙的递归XS进行一些泄漏检查,并且当我设法让我的所有引用计数很好地工作时非常高兴。这个Pure Perl编程示例如何泄漏?

想象一下,当我发现一个相对良性的Pure Perl泄漏时,我的震惊!

有人可以告诉我为什么这个看似无害的递归函数像疯子一样泄漏吗? (Linux,Ubuntu 12.10,64位)。

#!/usr/bin/perl 
use strict; 
use warnings; 
use Devel::Leak; 

sub annotated_hex { 
    my $annotated = shift; 
    if (ref $annotated ne 'HASH') { return '<' . (ref $annotated) . '>'; } 

    my $hex = ''; 
    if (defined $annotated->{hex}) { 
     $hex .= $annotated->{hex}; 
    } 
    if (defined $annotated->{elements}) { 
     if (ref $annotated->{elements} eq 'ARRAY') { 
      foreach my $element (@{ $annotated->{elements} }) { 
       $hex .= &annotated_hex ($element); 
      } 
     } else { 
      $hex .= '<Elements=' . (ref $annotated->{elements}) . '>'; 
     } 
    }   
    return $hex; 
} 

Devel::Leak::NoteSV (my $handle); 
my $annotated = { 'hex' => 'a824', 'elements' => [ { 'hex' => '0201', }, ] }; 
my $annotated_hex = &annotated_hex ($annotated); 

undef $annotated_hex; 
undef $annotated; 
Devel::Leak::CheckSV ($handle); 
1; 

输出是大量泄漏......

$ perl annotate.pl 
new 0x22d8a80 : SV = NULL(0x0) at 0x22d8a80 
    REFCNT = 1 
    FLAGS = (PADMY) 
new 0x22d8f78 : SV = NULL(0x0) at 0x22d8f78 
...[24 leaked entries in total] 

这是怎么回事与该?

+0

nit:你为什么用'&调用你的函数?我真的不认为这是问题,但它也似乎并不需要他们(颠覆原型)。 – 2013-04-30 01:40:39

+0

习惯的力量,我从Perl 4开始。:)而且不会影响泄漏。 :( – 2013-04-30 02:43:23

回答

0

什么是你的perl -V?它不会泄漏我在win32上的citrusperl v5.16.1,如果我可以发表评论,这将是一个评论:)

更新:这里是代码,更改循环量,更改数据结构的大小,它doesn 't grow

#!/usr/bin/perl -- 
use strict; 
use warnings; 
use Devel::Leak; 

sub annotated_hex { 
    my $annotated = shift; 
    if (ref $annotated ne 'HASH') { return '<' . (ref $annotated) . '>'; } 

    my $hex = ''; 
    if (defined $annotated->{hex}) { 
     $hex .= $annotated->{hex}; 
    } 
    if (defined $annotated->{elements}) { 
     if (ref $annotated->{elements} eq 'ARRAY') { 
      foreach my $element (@{ $annotated->{elements} }) { 
       $hex .= &annotated_hex ($element); 
      } 
     } else { 
      $hex .= '<Elements=' . (ref $annotated->{elements}) . '>'; 
     } 
    }   
    return $hex; 
} 

for(1..100){ 
    print ' ', Devel::Leak::NoteSV (my $handle); 
    my $annotated = { 
     'hex' => 'a824', 
     'elements' => [ 
      map {; { 'hex' => '0201'.$_ } } 1 .. (100*$_) 
     ], 
    }; 

    my $annotated_hex = &annotated_hex ($annotated); 

    undef $annotated_hex; 
    undef $annotated; 
    print ' ', Devel::Leak::CheckSV ($handle); 
} 
1; 
__END__ 
new 009EC17C : 
new 009EC1AC : 
new 009DF6CC : 
new 009DF89C : 
new 009DFC8C : 
new 009AAAE4 : 
new 009AAD04 : 
new 009AAFB4 : 
new 0099AEF4 : 
new 0099AF04 : 
new 0099AF14 : 
new 0099AF24 : 
new 0099AF84 : 
new 0099AF94 : 
new 0099AFD4 : 
new 0099AFE4 : 
new 0099AFF4 : 
new 0099B4A4 : 
new 0099B604 : 
new 003F915C : 
new 003F916C : 
new 003F91AC : 
new 003F91CC : 
new 003F91FC : 
2256 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 
2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 
2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 
2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 
2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 
2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 
2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 
2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 2280 
2280 2280 2280 2280 2280 2280 2280 2280 
+0

$ perl -v =“这是为x86_64-linux-gnu-thread-multi构建的perl 5,14版本,subversion 2(v5.14.2)”(perl -V有点太大而无法发表评论)! – 2013-04-30 21:59:48

+0

但是'perl -V'对于你的帖子来说不是太大 - 尽管我不认为它是必需的,但我已经更新了我的帖子 – optional 2013-05-13 04:27:31

0

我不确定'泄漏'是在这里使用的正确词汇。我增强你的榜样与多次调用annotated_hex和使用多个不同的散列引用和字符串,以及新的元素从CheckSV返回的总数明显高于NoteSV

换句话说总是25个,泄漏不发展。我怀疑25来自一些新的内部perl引用在评估你的函数时根据需要创建。

+0

嗯......我会在那个区域玩,看看那是什么显示... – 2013-04-30 22:01:28