Why is this perl program with a DBI connection to a MS SQL server over ODBC leaking memory?
I have several Perl programs that I maintain at work that have been running fine for years on various systems (WinXP, Win 2003, Linux). Recently we have deployed them for a new client on a 64 bit Windows 2008 Server running SQL Server 2008. The code ran fine for a bit then it stopped. Looking into it I saw that I was getting out-of-memory errors. Attempting to track down the leak I came up with the following sample program that withing a min or two claims about 40megs of memory and just keeps开发者_如何学Go growing. Any ideas?
use strict;
use warnings;
use DBI qw(:sql_types);
my $dbh = DBI->connect("DBI:ODBC:sample_db", "user", "pass");
my $query = $dbh->prepare("SELECT TOP 1 ID FROM TABLE");
while (1)
{
$query->execute();
while (my $row = $query->fetchrow_hashref() ){
print $row->{ID} . "\n";
}
$query->finish();
}
I'm running strawberry perl 5.12.2 but have been able to reproduce this on this box with the 5.10 build as well.
C:>perl -V
Summary of my perl5 (revision 5 version 12 subversion 2) configuration:
Platform:
osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
uname='Win32 strawberryperl 5.12.2.0 #1 Fri Nov 5 05:17:27 2010 i386'
config_args='undef'
hint=recommended, useposix=true, d_sigaction=undef
useithreads=define, usemultiplicity=define
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=undef, use64bitall=undef, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='gcc', ccflags =' -s -O2 -DWIN32 -DHAVE_DES_FCRYPT -DUSE_SITECUSTOMIZE -
DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -fno-strict-aliasing -mms-bitfields -
DPERL_MSVC`enter code here`RT_READFIX',
optimize='-s -O2',
cppflags='-DWIN32'
ccversion='', gccversion='4.4.3', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='long long', lseek
size=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='g++', ldflags ='-s -L"C:\strawberry\perl\lib\CORE" -L"C:\strawberry\c\li
b"'
libpth=C:\strawberry\c\lib C:\strawberry\c\i686-w64-mingw32\lib
libs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32
-lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion
-lodbc32 -lodbccp32 -lcomctl32
perllibs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladva
pi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lver
sion -lodbc32 -lodbccp32 -lcomctl32
libc=, so=dll, useshrplib=true, libperl=libperl512.a
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-mdll -s -L"C:\strawberry\perl\lib\CORE" -L"C:\st
rawberry\c\lib"'
Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV
PERL_IMPLICIT_CONTEXT PERL_IMPLICIT_SYS
PERL_MALLOC_WRAP PL_OP_SLAB_ALLOC USE_ITHREADS
USE_LARGE_FILES USE_PERLIO USE_PERL_ATOF
USE_SITECUSTOMIZE
Built under MSWin32
Compiled at Nov 5 2010 08:39:08
@INC:
C:/strawberry/perl/site/lib
C:/strawberry/perl/vendor/lib
C:/strawberry/perl/lib
.
There was a leak introduced in 1.24_2 which was not fixed until 1.26_3. From the changes file:
=head2 Changes in DBD::ODBC 1.26_3 November 18, 2010
Fixed rt 63108. The change to column binding in 1.24_2 was not complete and causes bound columns to be rebound on each execute wasting time and leaking memory. Found, diagnosed and proposed fix by Steve Bentley.
It is always worth checking the changelog for modules you use when something like this happens.
Turns out the problems was with the DBD::ODBC module. I had a slightly out of date version (1.26 I believe forgot to take note of it). Using cpan to upgrade to 1.29 took care of the problem.
精彩评论