Subject: | Proc::ProcessTable 0.41 issues negative rsize memory value on 64bit Linux |
For large memory consumptions a negative memory value is issued on 64bit
Linux for the method rss(). I can not see the same behaviour for the
size() method.
Called in this fashion (I know that _this_ call does not work, it's an
example):
${ Proc::ProcessTable->new()->table }[$my_index]->rss()
Attached is a test program. Called with:
uname -a ; ./leaking.pl 10000000
I get the output:
Linux mucsxbali09 2.4.21-47.2.ELsmp #1 SMP Tue Oct 10 18:31:18 EDT 2006
x86_64 x86_64 x86_64 GNU/Linux
initiating '10000000' hash values
v/rsize = 475918336 / 445153280 VAR($hash) = 108
v/rsize = 1446268928 / 1415000064 VAR($hash) = 475997837
v/rsize = 2543054848 / -1783611392 VAR($hash) = 67108940
...
The PERL Version is:
/opt/perl_5.8.8/.d/bin/perl -V
Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
Platform:
osname=linux, osvers=2.4.21-37.elhugemem, archname=i686-linux
uname='linux kiew080 2.4.21-37.elhugemem #1 smp wed sep 7 13:22:27
edt 2005 i686 i686 i386 gnulinux '
config_args='-Dprefix=/opt/perl_5.8.8 -Dmydomain=.muc.infineon.com
-Dcf_email=perl@muc.infineon.com -Uinstallusrbinperl
-Dperlpath=/opt/perl_5.8.8/.d/bin/perl
-Dinstallman1dir=/opt/perl_5.8.8/man/man1
-Dman1dir=/opt/perl_5.8.8/man/man1
-Dinstallman3dir=/opt/perl_5.8.8/man/man3
-Dman3dir=/opt/perl_5.8.8/man/man3 -Dperladmin=perl@muc.infineon.com
-Dprivlib=/opt/perl_5.8.8/.d/lib -Darchlib=/opt/perl_5.8.8/.d/lib
-Dsitelib=/opt/perl_5.8.8/.d/lib -Dsitearch=/opt/perl_5.8.8/.d/lib
-Dscriptdir=/opt/perl_5.8.8/.d/bin -Dsitescript=/opt/perl_5.8.8/.d/bin
-Ubincompat5005 -Dlibperl=libperlifx.so -Dcc=gcc
-Dldflags=-Wl,-rpath,/opt/perl_5.8.8/ext/lib -g
-Dbin=/opt/perl_5.8.8/.d/bin -Dbinexp=/opt/perl_5.8.8/.d/bin
-Dsitebin=/opt/perl_5.8.8/.d/bin -Dlocincpth=/opt/perl_5.8.8/ext/include
-Dloclibpth=/opt/perl_5.8.8/ext/lib -Dglibpth=/usr/lib /lib
-Duseshrplib -Uusethreads -Dpager=/usr/bin/less -Doptimize=-O2
-march=pentium3 -g -Dlddlflags=-shared
-Wl,-rpath,/opt/perl_5.8.8/ext/lib -g -Dotherlibdirs=/opt/perl_5.8.8/lib
-de'
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef
usemultiplicity=undef
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='gcc', ccflags ='-DDEBUGGING -fno-strict-aliasing -pipe
-Wdeclaration-after-statement -I/opt/perl_5.8.8/ext/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
optimize='-O2 -march=pentium3 -g',
cppflags='-DDEBUGGING -fno-strict-aliasing -pipe
-Wdeclaration-after-statement -I/opt/perl_5.8.8/ext/include
-I/usr/include/gdbm'
ccversion='', gccversion='4.0.3', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
alignbytes=4, prototype=define
Linker and Libraries:
ld='gcc', ldflags ='-Wl,-rpath,/opt/perl_5.8.8/ext/lib -g
-L/opt/perl_5.8.8/ext/lib'
libpth=/opt/perl_5.8.8/ext/lib /usr/lib /lib
libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
libc=/lib/libc-2.3.2.so, so=so, useshrplib=true, libperl=libperlifx.so
gnulibc_version='2.3.2'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E
-Wl,-rpath,/opt/perl_5.8.8/.d/lib/CORE'
cccdlflags='-fpic', lddlflags='-shared
-Wl,-rpath,/opt/perl_5.8.8/ext/lib -g -L/opt/perl_5.8.8/ext/lib'
Characteristics of this binary (from libperl):
Compile-time options: DEBUGGING PERL_MALLOC_WRAP USE_LARGE_FILES
USE_PERLIO
Built under linux
Compiled at Jul 17 2006 13:12:04
@INC:
/opt/perl_5.8.8/.d/lib
/opt/perl_5.8.8/lib
On SUN I could not reproduce it, but I think that is because I could not
get enough memory.
Maybe somebody has an idea how to fix that in the next release?
Best regards,
Stefan
Subject: | leaking.pl |
#!/opt/perl_5.8.8/.d/bin/perl -w # -DD
require Proc::ProcessTable;
require Proc::ProcessTable::Process;
use Devel::Size qw(size total_size);
sub process () { # find myself;
my $table = Proc::ProcessTable->new();
my $procs = $table->table;
foreach my $p (@$procs) {
return $p if ($p->pid == $$);
}
die("could not find myself");
}
sub vsize () { return process()->size; } # return virtual size
sub rsize () { return process()->rss; } # resulting size
sub SIZE ($\[$@%]) {
my $text = shift;
my $ref = shift;
my $vsize = vsize();
my $rsize = rsize();
my $size = total_size($ref);
print("v/rsize = $vsize / $rsize VAR($text) = $size\n");
}
sub allocate_hash (\@) {
my $l = shift;
my $h = {};
SIZE('$hash', $h);
foreach my $key (@$l) { $h->{$key} = undef; }
SIZE('$hash', $h);
foreach my $key (@$l) { delete($h->{$key}); }
SIZE('$hash', $h);
print ("\n");
return $h;
}
my $upper = $ARGV[0] ? $ARGV[0] : 10000000;
my @list = 1..$upper;
print("initiating '$upper' hash values\n\n");
allocate_hash(@list);
#my $var1 = {};
allocate_hash(@list);
#my $var2 = {};
allocate_hash(@list);
#my $var3 = {};
allocate_hash(@list);
#my $var4 = {};
allocate_hash(@list);
#my $var5 = {};