Perl Out of Memory

时间:2012-02-07 18:35:32

标签: windows perl memory

我有一个脚本可以读取两个csv文件并对它们进行比较,以确定其中一个ID是否也出现在另一个中。我收到的错误如下:

  

在67112960字节的“大”请求期间内存不足,总sbrk()为348203008字节

现在代码:

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\n";
}
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\n";

        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\n";
                    $doc_counter++;
                } else {
                    print OUT "$doc_id,PAGE NOT FOUND IN OPT FILE\n";
                    $page_counter++;
                }
            }
        }
    }
close(DAT);
close(OUT);

print "Found $page_counter missing pages and $doc_counter missing document(s)";

基本上我从我正在检查的文件中获取所有ID,以查看ID是否存在。然后我循环并生成另一个文件的ID,因为它们是作为范围呈现的。然后我获取生成的ID并在ID的散列中检查它。

还忘记注意我使用的是Windows

3 个答案:

答案 0 :(得分:2)

你没有使用use warnings;,你没有检查打开文件的错误,也没有打印出显示你正在阅读的行的调试语句。

你知道输入文件是什么样的吗?如果它没有换行符,则表示您正在同时读取整个文件,如果它很大,则会是灾难性的。注意你如何解析文件。

答案 1 :(得分:1)

我不确定这是否是导致错误的原因,但在您正在阅读DAT的循环中,您可能想要替换它:

        (my $pre = @DAT_Line[$beg_doc]) =~ s/[0-9]//g;

用这个:

        (my $pre = $DAT_Line[$beg_doc]) =~ s/[0-9]//g;

和其他两行相同。

答案 2 :(得分:0)

您正在关闭OUT文件句柄,然后尝试在DAT循环内打印到它,我认为可能会输出到随机内存,因为您关闭了FILEHANDLE - 这让我感到惊讶没有输出错误。

删除第一个close(OUT);并查看是否有所改善。


我仍然不知道你的问题是什么,如果它是关于错误信息,那就意味着你的内存耗尽。如果它是关于消息本身 - 你试图消耗太多的内存。如果这就是你消耗太多内存的原因,我首先会问你是否阅读了我上面的消息,然后我会问你的系统有多少内存,然后我会跟进看看如果你采取了正则表达式。