什么导致记忆不断上升perl?

时间:2016-04-25 10:24:02

标签: linux perl memory

问题

我创建了一个简单的perl脚本来读取日志文件并异步处理数据。

我面临的问题是脚本在运行的时间越长,就会持续使用更多内存。这似乎受其处理的数据量的影响。我遇到的问题是我无法确定究竟是什么使用了所有这些内存,以及它是否是泄漏或其他东西只是坚持它。

问题

如何修改以下脚本以使其不再持续消耗内存?

代码

#Multithreaded to read multiple log files at the same time.

use strict;
use warnings;

use threads;
use Thread::Queue;
use threads::shared;

my $logq = Thread::Queue->new();
my %Servers :shared;
my %servername :shared;

sub csvsplit {
        my $line = shift;
        my $sep = (shift or ',');

        return () unless $line;

        my @cells;
        my $re = qr/(?:^|$sep)(?:"([^"]*)"|([^$sep]*))/;

        while($line =~ /$re/g) {
                my $value = defined $1 ? $1 : $2;
                push @cells, (defined $value ? $value : '');
        }

        return @cells;
}


sub process_data
{
        while(sleep(1)){

                if ($logq->pending())
                {
                        my %sites;
                        my %returns;
                        while($logq->pending() > 0){
                                my $data = $logq->dequeue();
                                my @fields = csvsplit($data);
                                $returns{$fields[$#fields - 1]}++;
                                $sites{$fields[$#fields]}++;
                        }
                print "counter:$_, value=\"$sites{$_}\" />\n" for (keys%sites);
                print "counter:$_, value=\"$returns{$_}\" />\n" for (keys%returns);

                }
        }

}

sub read_file
{
        my $myFile=$_[0];
        open(my $logfile,'<',$myFile) || die "error";
        my $Inode=(stat($logfile))[1];
        my $fileSize=(stat($logfile))[7];
        seek $logfile, 0, 2;
        for (;;) {
                while (<$logfile>) {
                        chomp( $_ );
                        $logq->enqueue( $_ );
                }
                sleep 5;
                if($Inode != (stat($myFile))[1] || (stat($myFile))[7] < $fileSize){
                        close($logfile);
                        while (! -e $myFile){
                                sleep 2;
                        }
                        open($logfile,'<',$myFile) || die "error";
                        $Inode=(stat($logfile))[1];
                        $fileSize=(stat($logfile))[7];
                }
                seek $logfile, 0, 1;
        }

}


my $thr1 = threads->create(\&read_file,"log");
my $thr4 = threads->create(\&process_data);
$thr1->join();
$thr4->join();

观察和相关信息

当程序有数据要处理时,内存似乎只会增加,如果我离开它,它会维持当前的内存使用量。

对于更大的吞吐量,内存似乎只会增加,并且同时在大约2000行中每5秒增加大约半个Mb。

我没有包含csv,因为我认为它不相关。如果您这样做并希望我添加它,请提供正确的理由。

功能

GNU bash, version 3.2.57(1)-release (s390x-ibm-linux-gnu)
perl, v5.10.0

我已经查看过其他问题,但找不到太多相关性。如果这是重复或相关信息在另一个问题中,请随意标记为欺骗并生病检查。

需要更多信息才能询问。

1 个答案:

答案 0 :(得分:2)

原因可能是Thread::Queue的大小无限制。如果生产者线程比消费者线程更快,那么您的队列将继续增长。所以你应该只是limit the size of your queue。例如,要设置1,000个队列项的限制:

$logq->limit = 1000;

(顺便使用pending方法的方法是错误的。只有在返回值未定义的情况下才应该终止。)