Hi,
I used another script (see below) making multiple connections and now I
see really strange results.
Running in a "standard" DBI, results shows some memory fluctuation:
# perl test6.pl
INIT count: 9116
PRE count: 12653
POST 100 count: 12754
POST 200 count: 12734
POST 300 count: 12714
POST 400 count: 12694
POST 500 count: 12674
POST 600 count: 12654 <-- near no leak
POST 700 count: 12754
POST 800 count: 12734
POST 900 count: 12714
POST 1000 count: 12694
POST 1100 count: 12674
POST 1200 count: 12654
POST 1300 count: 12754
POST 1400 count: 12734
POST 1500 count: 12714
POST 1600 count: 12694
POST 1700 count: 12674
POST 1800 count: 12654
POST 1900 count: 12754
POST 2000 count: 12734
However, recompiling DBI and disabling weak references, as Tim said here:
===
#ifdef sv_rvweaken
if (1) {
Change the 1 to a 0 to disable the use of weakrefs which was added in 1.49.
===
http://coding.derkeiler.com/Archive/Perl/perl.dbi.users/2006-07/msg00076.html
Shows no leaks at all:
# perl test6.pl
INIT count: 9116
PRE count: 12650
POST 100 count: 12651
POST 200 count: 12651
POST 300 count: 12651
POST 400 count: 12651
POST 500 count: 12651
POST 600 count: 12651
POST 700 count: 12651
POST 800 count: 12651
POST 900 count: 12651
POST 1000 count: 12651
POST 1100 count: 12651
POST 1200 count: 12651
POST 1300 count: 12651
POST 1400 count: 12651
POST 1500 count: 12651
POST 1600 count: 12651
POST 1700 count: 12651
POST 1800 count: 12651
POST 1900 count: 12651
POST 2000 count: 12651
So I am really confused, is this a bug in the weak references code? or
is this a buffer, cache or similar? Is this working as designed?
Test script:
===
#!/usr/bin/perl
use Devel::Leak;
use DBI;
my $DLcount;
my $DLhandle;
my $i = 0;
my $con;
$DLcount = Devel::Leak::NoteSV($DLhandle);
print "INIT count: $DLcount\n";
$con = DBI->connect('DBI:mysql:database=test;host=127.0.0.1', 'root',
'', {PrintError => 0,PrintWarn=>0});
undef $con;
$DLcount = Devel::Leak::NoteSV($DLhandle);
print "PRE count: $DLcount\n";
for (1..20) {
for (1..100) {
$con = DBI->connect('DBI:mysql:database=test;host=127.0.0.1',
'root', '', {PrintError => 0,PrintWarn=>0});
undef $con;
$i++;
}
$DLcount = Devel::Leak::NoteSV($DLhandle);
print "POST $i count: $DLcount\n";
}
===
-------- Original Message --------
Subject: Memory leak in connect and undef
From: Carlos Velasco <[email protected]>
To: [email protected]
Date: Martes, 18 De Septiembre De 2012 23:10:26
> Hello,
>
> Debugging a long term perl daemon for memory leaks I have found out that
> just a DB connect and undef leaks.
>
> This simple code leaks:
> ===
> #!/usr/bin/perl
>
> use DBI;
>
> my $con;
>
> $con = DBI->connect('DBI:mysql:database=test;host=127.0.0.1', 'root',
> 'pass', {PrintError => 0,PrintWarn=>0});
> undef $con;
> ===
>
> I used Devel::Leak and opened a bug in DBD::mysql
> http://bugs.mysql.com/bug.php?id=66859
>
> But the problem seems to be in DBI.
>
> Using Devel::leak::Object reveals leaking in DBI::var.
>
> This code:
> ===
> #!/usr/bin/perl
>
> # Track every object including where they're created
> use Devel::Leak::Object qw{ GLOBAL_bless };
> $Devel::Leak::Object::TRACKSOURCELINES = 1;
>
> use DBI;
>
> my $con;
>
> for (1..1000) {
> $con = DBI->connect('DBI:mysql:database=test;host=127.0.0.1', 'root',
> 'pass', {PrintError => 0,PrintWarn=>0});
> $con->disconnect();
> undef $con;
> }
> ===
>
> Outputs:
> ===
> Tracked objects by class:
> Config 1
> DBI::var 5
>
> Sources of leaks:
> Config
> 1 from /usr/lib64/perl5/5.16.1/x86_64-linux-thread-multi/Config.pm
> line: 73
> DBI::var
> 5 from
> /usr/lib64/perl5/site_perl/5.16.1/x86_64-linux-thread-multi/DBI.pm line: 306
> ===
>
> I used DBI-1.622_901 (latest version I saw), and line 306 is:
> sub DBI::var::TIESCALAR{ my $var = $_[1]; bless \$var, 'DBI::var'; }
>
> Don't know how to debug this further.
>
> Perl is 5.16.1
> DBD::mysql is 4.022
> mysql is mysql-5.5.27.tar.gz
>
>
> Also, it seems these leaks have been there from long time ago:
> https://bugs.launchpad.net/ubuntu/+source/libdbd-mysql-perl/+bug/51746
>
> Regards,
> Carlos Velasco
>