我最近在一个特别粗糙的递归XS上执行了一些泄漏检查,当我设法让所有引用计数工作得很好时,我非常高兴。
想象一下当我发现一个相对温和的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 :(得分:0)
你的perl -V
是什么?它在win32 citrusperl v5.16.1上没有泄漏,如果我可以评论这将是一个评论:)
更新:这里是代码,更改循环量,更改数据结构的大小,它不会增长
#!/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
答案 1 :(得分:0)
我不确定'泄漏'是否适合在这里使用。我通过多次调用annotated_hex
并使用多个不同的哈希引用和字符串来扩充您的示例,并且从CheckSV
返回的新元素的总数总是比NoteSV
中的那些多25个
换句话说,泄漏没有增长。我怀疑25来自于评估函数时根据需要创建的一些新的内部perl引用。