I'm having some memory leak issues in a perl script that I'm running for extended periods of time, where the amount of memory that perl is taking up just continues to grow. Because of this, I am trying to use Devel::Leak to track down the leak. I discovered that whenever I call DBI's prepare
method, the number of scalar values returned by Devel::Leak
goes up by one. Below is I test script I've put together that does what I'm describing:
#!/usr/bin/perl
use strict;
use Devel::Leak;
use DBI;
START:
my $handle; # apparently this doesn't need to be anything at all
my $leaveCount = 0;
my $enterCount = Devel::Leak::NoteSV($handle);
print "ENTER: $enterCount SVs\n";
{
# CONFIG VARIABLES
my $platform = "mysql";
my $database = "db";
my $host = "localhost";
my $port = "3306";
my $user = "user";
my $pw = "pass";
#DATA SOURCE NAME
my $dsn = "dbi:mysql:$database:$host:3306";
# PERL DBI CONNECT
my $dbh = DBI->connect($dsn, $user, $pw);
$dbh->prepare("SELECT * FROM table"); # The script seems to gain one SV without this
# line here, but since this is my issue in my
# main script I decided to leave it in
# undef $dbh; I tried undef-ing this, but it made no difference
}
$leaveCount = Devel::Leak::CheckSV($handle);
print "\nLEAVE: $leaveCount SVs\n";
sleep(1);
goto START;
So is there something I'm doing wrong here, or is this a memory leak in the DBI module? Also, I know that adding one SV every time around the loop isn't a huge deal, and that I most likely have larger memory leaks elsewhere that are causing perl to take so much of the server's memory. However, I'd still like to fix this if I could. Coder's curiosity :)
UPDATE:
The first time through it seems to add about 3,000 SV's, and then every time after that it goes up 1 at a time.
prepare_cached
instead ofprepare
it will fix it. I tried it out and it initially jumps from 77452 SV's to 77482 SV's the first time I call prepare, but then stays at 77482. So although I guess this 'works', I'd prefer to have it work like yours does where there are no inconsistencies. – Cobbie$handle
at each iteration and use it as a parameter in the call ofD::L::n/cSV
(where its used as a call-by-ref param according to the docs), which means the optimizer cannot just assume that the old value is no longer in use. so i would expect a new SV per iteration until you leave the scope of the$handle
declaration. easy to check: drop the block in curly brackets and check whether the increment persists. – Glycolysis$sth->finish
? – Partinmy $sth = $dbh->prepare($sql);
capturing the return from the prepare. Does that make any difference? ...No...It reproduces for me with Perl 5.16.0 and DBI 1.622, and with DBD::Informix instead of DBD::MySQL. Consequently, it is likely to be an issue in DBI rather than the DBD modules per se. – Pleinair