Sql server 为什么这个通过ODBC与MS SQL server建立DBI连接的perl程序会泄漏内存?
我在工作中维护了几个Perl程序,这些程序在各种系统(WinXP、Win2003、Linux)上运行了多年。最近,我们为运行SQL Server 2008的64位Windows 2008服务器上的新客户端部署了它们。代码运行了一段时间后就停止了。看着它,我发现我的记忆中出现了错误。为了追踪漏洞,我提出了下面的示例程序,只需一两分钟,它就可以获得大约40兆字节的内存,而且还在不断增长。有什么想法吗Sql server 为什么这个通过ODBC与MS SQL server建立DBI连接的perl程序会泄漏内存?,sql-server,windows,database,perl,dbi,Sql Server,Windows,Database,Perl,Dbi,我在工作中维护了几个Perl程序,这些程序在各种系统(WinXP、Win2003、Linux)上运行了多年。最近,我们为运行SQL Server 2008的64位Windows 2008服务器上的新客户端部署了它们。代码运行了一段时间后就停止了。看着它,我发现我的记忆中出现了错误。为了追踪漏洞,我提出了下面的示例程序,只需一两分钟,它就可以获得大约40兆字节的内存,而且还在不断增长。有什么想法吗 use strict; use warnings; use DBI qw(:sql_types);
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();
}
我运行的是草莓Perl5.12.2,但在5.10版本中也能在这个盒子上重现这一点
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
.
原来问题出在DBD::ODBC模块上。我有一个稍微过时的版本(我想是1.26忘了记下了)。使用cpan升级到1.29解决了该问题。1.24_2中引入了泄漏,直到1.26_3才修复。从更改文件: =DBD中的头2变化::ODBC 1.26_3 2010年11月18日 修正了rt 63108。1.24_2中对列绑定的更改未被执行 完成并使绑定列在每次执行时反弹 浪费时间和泄漏内存。发现、诊断和建议修复 史蒂夫·本特利
当发生类似情况时,总是值得检查您使用的模块的更改日志。From:在获取所有行的循环之后添加finish调用是一个常见错误,不要这样做,它可以掩盖未捕获的获取错误等真实问题。感谢@eugene,在使用DBI多年后,我仍然在学习新技巧,一定会喜欢它。