请帮我了解一下,为什么引用计数是每个串联的增长? 我将在重载子中返回相同的对象,并且希望refcount保持不变。但是,似乎每次Perl都会在某个地方克隆和存储对象。为什么以及如何避免这种情况?
我还期望,该对象将在退出作用域后立即被销毁,但是由于非零引用计数,因此仅在全局销毁阶段销毁了该对象。这看起来像是内存泄漏。
#!/usr/bin/env perl
use strict;
use warnings;
use Devel::Refcount qw[refcount];
package AAA {
use Devel::Refcount qw[refcount];
use overload
'.' => sub {
print 'CONCAT, REFCOUNT: ', refcount( $_[0] ), "\n";
# return AAA->new;
return $_[0];
},
fallback => 0;
sub new { return bless {}, $_[0] }
sub DESTROY { print "DESTROY\n" }
}
print "--- start\n";
{
my $o = AAA->new;
my $s = '1' . ( '2' . ( '3' . ( '4' . ( '5' . $o ) ) ) );
print "--- exit scope\n";
print 'REFCOUNT: ', refcount($o), "\n";
}
print "--- end\n";
1;
经过测试
输出
--- start
CONCAT, REFCOUNT: 1
CONCAT, REFCOUNT: 3
CONCAT, REFCOUNT: 5
CONCAT, REFCOUNT: 7
CONCAT, REFCOUNT: 9
--- exit scope
REFCOUNT: 6
--- end
DESTROY
答案 0 :(得分:7)
就像延迟的DESTROY
消息一样,向对象添加弱引用也表明有泄漏。该漏洞似乎是Perl 5.28中引入的。
use strict;
use warnings;
use Scalar::Util qw( weaken );
package AAA {
use overload
'.' => sub { $_[0] },
fallback => 0;
sub new { return bless {}, $_[0] }
sub DESTROY { print "DESTROY\n" }
}
my $w;
{
my $o = AAA->new;
weaken($w = $o);
my $s = '1' . ( '2' . ( '3' . ( '4' . ( '5' . $o ) ) ) );
print "Exiting scope...\n";
}
print "leak!\n" if defined($w);
#use Devel::Peek;
#Dump($w);
print "Global destruction...\n";
输出(5.28之前):
Exiting scope...
DESTROY
Global destruction...
输出(5.28.0和5.28.1):
Exiting scope...
leak!
Global destruction...
DESTROY
请使用 perlbug
命令行实用工具进行报告。
该错误报告可以找到here。
它已在5.30中修复。可能在5.28.2中已修复。