Windows - Perl ude af hukommelse

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har et script, der læser to csv-filer og sammenligner dem for at finde ud af, om et ID, der vises i et, også vises i det andet. Fejlen jeg modtager er som følger:



  Uden hukommelse under 'stor' anmodning om 67112960 bytes er den samlede sbrk () 348203008 bytes



Og nu for koden:


use strict;
use File::Basename;

my $DAT     = $ARGV[0];
my $OPT     = $ARGV[1];

my $beg\_doc = $ARGV[2];
my $end\_doc = $ARGV[3];

my $doc\_counter  = 0;
my $page\_counter = 0;
my \%opt\_beg\_docs;
my \%beg\_docs;

my ($fname, $dir, $suffix) = fileparse($DAT, qr/.[^.]*/);
my $outfile = $dir . $fname . ".\_IMGLOG";

open(OPT, "<$OPT");
    while(<OPT>){
        my @OPT\_Line = split(/,/, $\_);
        $beg\_docs{@OPT\_Line[0]} = "Y" if(@OPT\_Line[3] eq "Y");
        $opt\_beg\_docs{@OPT\_Line[0]} = "Y";
    }
close(OPT);
open(OUT, ">$outfile");
while((my $key, my $value) = each \%opt\_beg\_docs){

    print OUT "$key
";
}
close(OUT);

open(DAT, "<$DAT");

    readline(DAT); #skips header line
    while(<DAT>){

        $\_ =~ s/xFE//g;

        my @DAT\_Line = split(/x14/, $\_);

        #gets the prefix and the range of the beg and end docs
        (my $pre = @DAT\_Line[$beg\_doc]) =~ s/[0-9]//g;
        (my $beg = @DAT\_Line[$beg\_doc]) =~ s/D//g;
        (my $end = @DAT\_Line[$end\_doc]) =~ s/D//g;

        #print OUT "BEGDOC: $beg ENDDOC: $end
";

        foreach($beg .. $end){
            my $doc\_id = $pre . $\_;

            if($opt\_beg\_docs{$doc\_id} ne "Y"){
                if($beg\_docs{$doc\_id} ne "Y"){
                    print OUT "$doc\_id,DOCUMENT NOT FOUND IN OPT FILE
";
                    $doc\_counter++;
                } else {
                    print OUT "$doc\_id,PAGE NOT FOUND IN OPT FILE
";
                    $page\_counter++;
                }
            }
        }
    }
close(DAT);
close(OUT);

print "Found $page\_counter missing pages and $doc\_counter missing document(s)";


Dybest set får jeg alle ID'erne fra den fil, jeg kontrollerer for at se om ID'et eksisterer. Så løber jeg over og genererer ID'erne til den anden fil, fordi de er præsenteret som en rækkevidde. Så tager jeg det genererede ID og kontrollerer det i ID'ernes hash.


Glemte også at bemærke, at jeg bruger Windows

Bedste reference


Jeg er ikke sikker på, om det er årsagen til din fejl, men inden for dit loop, hvor du læser DAT, vil du sandsynligvis erstatte dette:


        (my $pre = @DAT\_Line[$beg\_doc]) =~ s/[0-9]//g;


med dette:


        (my $pre = $DAT\_Line[$beg\_doc]) =~ s/[0-9]//g;


og det samme for de to andre linjer der.

Andre referencer 1


Du bruger ikke use warnings;. Du kontrollerer ikke for fejl ved åbning af filer, og du udskriver ikke fejlfindingserklæringer, der viser de linjer, du læser.


Ved du, hvad inputfilen ser ud? Hvis det ikke har nogen linjeskift, læser du hele filen på én gang, hvilket vil være katastrofalt, hvis det er stort. Vær opmærksom på, hvordan du analyserer filen.

Andre referencer 2


Du lukker dit OUT filhåndtag og forsøger derefter at udskrive til det inde i DAT -sløjfen, som jeg tror kunne udgive til tilfældig hukommelse, siden du lukkede FILEHANDLE - overraskede det ikke Udfør en fejl.


Fjern den første close(OUT); og se om det forbedres.





Jeg ved stadig ikke, hvad dit spørgsmål er, hvis det handler om fejlmeddelelsen, betyder det, at du har løbet tør for hukommelsen. Hvis det handler om selve meddelelsen, forsøger du at forbruge for meget hukommelse. hvorfor bruger du for meget hukommelse, spørger jeg først, om du læser min besked ovenfor, så spørger jeg hvor meget hukommelse dit system har, så følger jeg op med at se, om det forbedres, hvis du tager den regex væk.