我正在運行一個perl腳本,該腳本崩潰時出現內存不足錯誤。 腳本在具有128 Gb內存的計算機上運行在Ubuntu Linux下。在提交時,大部分內存都可用,但腳本隨着其使用的內存超過略高於8Gb的值而死亡。機器(和操作系統)是64位的。Perl內存不足但存在大量可用內存
我一直在尋找perl內存分配的限制,但我發現的唯一限制是機器內存,在這種情況下,即使沒有考慮交換分區,也有很多。
這是我第二次遇到這個問題。我第一次使用不同的腳本,發生了同樣的事情。有沒有人有解釋?我看到的唯一可能是perl對內存分配有一些限制,但是我在網上搜索的所有結果似乎與這種可能性相矛盾。
在此先感謝
編輯1: 操作系統是Fedora Linux系統,而不是Ubuntu Linux操作系統。對不起,我感到困惑。
編輯2: 下面是導致錯誤的代碼部分:
open($psFullInput, "<", "fullPsIn.dat");
$counter = <$psFullInput>; # First element is counter of spectra
while ($line = <$psFullInput>) {
@elems = split(" ",$line);
$xx = shift(@elems);
$yy = shift(@elems);
$freq = shift(@elems);
$psStored[$xx][$yy] = [];
push(@{$psStored[$xx][$yy]}, @elems);
}
close($psFullInput);
前面的腳本在做類似的事情,不同的是數組元素不是從一個文件,但在那裏讀一些計算的結果。
EDIT 3:perl的-V的 結果:
Summary of my perl5 (revision 5 version 16 subversion 3) configuration:
Platform:
osname=linux, osvers=3.10.9-200.fc19.x86_64, archname=x86_64-linux-thread-multi
uname='linux buildvm-01.phx2.fedoraproject.org 3.10.9-200.fc19.x86_64 #1 smp wed aug 21 19:27:58 utc 2013 x86_64 x86_64 x86_64 gnulinux '
config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Dccdlflags=-Wl,--enable-new-dtags -Dlddlflags=-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Wl,-z,relro -DDEBUGGING=-g -Dversion=5.16.3 -Dmyhostname=localhost [email protected] -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize'
hint=recommended, useposix=true, d_sigaction=define
useithreads=define, usemultiplicity=define
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=define, use64bitall=define, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic',
cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
ccversion='', gccversion='4.8.2 20131017 (Red Hat 4.8.2-1)', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='gcc', ldflags =' -fstack-protector'
libpth=/usr/local/lib64 /lib64 /usr/lib64
libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc -lgdbm_compat
perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
libc=, so=so, useshrplib=true, libperl=libperl.so
gnulibc_version='2.17'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,--enable-new-dtags -Wl,-rpath,/usr/lib64/perl5/CORE'
cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Wl,-z,relro '
Characteristics of this binary (from libperl):
Compile-time options: HAS_TIMES MULTIPLICITY PERLIO_LAYERS
PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT
PERL_MALLOC_WRAP PERL_PRESERVE_IVUV USE_64_BIT_ALL
USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES
USE_LOCALE USE_LOCALE_COLLATE USE_LOCALE_CTYPE
USE_LOCALE_NUMERIC USE_PERLIO USE_PERL_ATOF
USE_REENTRANT_API USE_SITECUSTOMIZE
Built under linux
Compiled at Nov 11 2013 12:36:47
%ENV:
PERL5LIB="/home/parisia/lib/perl5/lib64/perl5"
@INC:
/home/parisia/lib/perl5/lib64/perl5
/usr/local/lib64/perl5
/usr/local/share/perl5
/usr/lib64/perl5/vendor_perl
/usr/share/perl5/vendor_perl
/usr/lib64/perl5
/usr/share/perl5
.
EDIT 4: 這裏是一個短碼再現的問題。正如你所看到的,我只是填滿了記憶。
use strict;
use warnings;
my ($xx,$yy); # Coordinate variables
my (@elems); # Array of elements to be stored on each matrix position
# Generate an array of 3000 floating point values.
# The list will be added to each array element. In the true script
# of course, each element has a list of completely different values.
# Here I use the same list of values for simplicity.
for ($xx = 1; $xx < 3000; $xx++) {
push(@elems, 1+$xx/10000);
}
# Fill in each matrix element with the generated array
my @psStored;
for ($xx = 0; $xx < 300; $xx++) {
print "Row [$xx]\n";
for ($yy = 0; $yy < 300; $yy++) {
push(@{$psStored[$xx][$yy]}, @elems);
}
}
這就是「自由」在崩潰之前(也有在計算機上運行一些並行進程)結果:
[[email protected] ~]$ free
total used free shared buffers cached
Mem: 132015788 46395504 85620284 0 217192 16979772
-/+ buffers/cache: 29198540 102817248
Swap: 268435452 0 268435452
更新1
我進一步調查。建議我使用Devel :: Size並檢查$ psStored的大小。輸出的最後幾行(打印在$ YY每個週期結束時的大小)爲:
Row [226]
8772773032
Row [227]
8811419600
Row [228]
Out of memory!
當腳本給出錯誤的過程的大小是: VIRT:8943960,RES:8.406克
然而,我試圖下面的腳本,其分配一個給定的大小(千兆字節)的字符串的命令行上指定:
use strict;
use warnings;
my $size = $ARGV[0];
print "$size GB ";
$size = int($size * 1000000000);
print "($size bytes)...\n";
my $var = "x" x $size;
print "Allocated\n";
此腳本具有大的分配沒有問題。例如,我可以請求30 GB,並且在腳本完成之前從「top」獲得以下輸出: VIRT:56.004g,RES:0。054t
因此,在處理數組時,有一些干擾分配,但我不明白髮生了什麼。我也嘗試過使用哈希,但我在8-9GB左右得到相同的限制。
您的意思是GB(字節)而不是Gb(位),對不對?你能告訴我們這個腳本使用的大部分8 GB的分配是什麼嗎?是很多小塊還是一些大塊?有沒有想過在它耗盡的時候它要分配多少內存?你有沒有試過在調試器中運行? –
嘗試編輯您的問題並粘貼在'perl -V'的輸出中 –
@JohnZwinck 是千兆字節。我認爲它是小塊。我將編輯該問題以放置出現錯誤的代碼部分。 – Andrea