2014-07-16 82 views
0

我得到這個瘋狂的消息:perl的錯誤「內存不足」的glibc檢測 - 如何解決

Out of memory! 
*** glibc detected *** perl: double free or corruption (!prev): 0x00000003f8f89690 *** 
======= Backtrace: ========= 
/lib64/libc.so.6[0x372bc75916] 
/lib64/libc.so.6[0x372bc78443] 
/usr/lib64/perl5/CORE/libperl.so(Perl_pregfree+0xd1)[0x3c5da74581] 
/usr/lib64/perl5/CORE/libperl.so(Perl_op_clear+0xeb)[0x3c5da3829b] 
/usr/lib64/perl5/CORE/libperl.so(Perl_op_free+0x15c)[0x3c5da3670c] 
/usr/lib64/perl5/CORE/libperl.so(Perl_op_free+0xbc)[0x3c5da3666c] 
======= Memory map: ======== 
00400000-00401000 r-xp 00000000 08:01 2229974       /usr/bin/perl 
00601000-00603000 rw-p 00001000 08:01 2229974       /usr/bin/perl 
0146c000-3f90ce000 rw-p 00000000 00:00 0         [heap] 
372b800000-372b820000 r-xp 00000000 08:01 4587522      /lib64/ld-2.12.so 
...(alot of these).... 
=>> PBS: job killed: vmem 17400672256 exceeded limit 17179869184 

當我跑了,我已經在之前(小巧的文件5-10GB)多次使用的腳本較大的文件(50GB)。我用Google搜索周圍,真的不明白我的代碼的問題可能是什麼有關這些問題的答案所以這裏是我的代碼:

my ($ethnicity) = @ARGV; 
my @map; 

open ($fh, "<", "/path/$filename") or die ("Unable to open input file: $!"); 

open ($fh4, "<", "/path/$filename")  or die ("Unable to open input file: $!"); 
my @ID = <$fh4>; 

open ($fh2, ">", "/path/$filename") or die ("Unable to open output file: $!"); 
open ($fh3, ">", "/path/$filename") or die ("Unable to open output file: $!"); 


my $i=0; 
my $j=0; 

print "The .ped and .map files are being generated\n"; 

while( my $line = <$fh>){ 
if ($.<3){ 
    $map[$j] = $line; 
    $j++;} 
else{ 
    my $temp = $line; 
    $temp =~ m/(\d*) (.*)/; 
    chomp($temp); 
    my $ID = $1; 
    print "$ID- "; 
    my $geno = $2; 
    $geno =~ s /([ATCG])([ATCG])/$1 $2/g; 

    $temp = $ID[$i]; 
    $temp =~ m/(\d*) (1 0 0 [012] [012])/; 
    print "$1\n"; 
    if($ID eq $1){ 
      print $fh2 "$ID $2 $geno\n"; 
      $i++;} 
    else{next;} 
    } 
} 

close $fh; 
close $fh2; 

我做了什麼錯?我認爲我編碼它一行一行地查看,並逐行寫入文件以節省內存。

+0

任何理由相信「內存不足!」 (當程序的大小超過16GiB時)意味着除了內存之外的其他東西? – ikegami

+0

嗯我真的不這麼認爲 - 羣集有> 300GB的空間使用 – roserose

+0

內存(RAM),而不是磁盤空間 – ikegami

回答

0

您正在將整個文件打開爲$fh4加載到內存中,但沒有理由。

my $line_from_fh4 = <$fh4>; 
my ($id_from_fh4, $rest_from_fh4) = $line_from_fh4 =~ m/(\d*) (1 0 0 [012] [012])/; 

while(my $line = <$fh>) { 
    if ($.<3) { 
     push @map, $line; 
     next; 
    } 

    chomp($line); 

    my ($ID, $geno) = $line =~ m/(\d*) (.*)/; 
    $geno =~ s/[ATCG]\K(?=[ATCG])/ /g; 

    print "$ID- $id_from_fh4\n"; 

    if ($ID eq $id_from_fh4){ 
     print $fh2 "$ID $rest_from_fh4 $geno\n"; 
     $line_from_fh4 = <$fh4>; 
     ($id_from_fh4, $rest_from_fh4) = $line_from_fh4 =~ m/(\d*) (1 0 0 [012] [012])/; 
    } 
} 
+0

哇 - 這減少了很多我的代碼:)但它不工作。我累了$ fh4仍然開始讀入整個文件這一行:: my $ line_from_fh4 = <$fh4>;當我需要它去下一個geno線時,這並不代表我需要它去下一個geno線,但保持在$ fh4線上,直到匹配發生在標量上下文中的 – roserose

+0

'<$fh4>'(因爲它在'my $ line_from_fh4 = <$fh4>; ')讀取一行,默認情況下,行被定義爲「直到遇到第一個換行符」。所以如果你說的是真的,你的文件只有一行,或者你改變了默認值(通過改變'$ /')。 – ikegami

+0

Re「當我需要它去下一個geno線時,這個doth't佔了,但留在$ fh4線,直到一個匹配的人」,是的,它確實。當匹配發生時,它只會到'$ fh4'的下一行。 – ikegami