Perl线程过多的内存使用

时间:2014-11-11 10:32:10

标签: multithreading perl memory memory-leaks

我编写了一个永远作为守护进程运行的Perl脚本。

my $CHILD_THREADS_CNT=5;

my  $q= new Thread::Queue();

sub processJob{
    while (defined(my $taskHandle = $q->dequeue()) ) {
        my $obj=jobProcesser->new();
        my $result=$obj->getOutput(taskHandle);
        #jobProcessor is the large modules that computes/manipulates the job
        //MySql Query to insert '$result' into DB
    }
}

#Daemon subroutine
sub daemon{
    while (1){
        my @new_request=   #'My SQL Queries that returns all  new requests from db'
        for (@new_request){
            $q->enqueue($_);
        }
        sleep 5;
    }
}
#Main thread scans the db, and, enqueue the new job in a queue.
my $scanDB=threads->create(\&daemon);

#children perform processing
my  @child=map threads->create(\&processJob), 1..CHILD_THREADS_CNT;

$scanDB->join;
$q->enqueue(undef) for 1..CHILD_THREADS_CNT;
for (@child){
    $_->join;
}

我使用nohup在unix(Perl v5.8.8)中运行此脚本。 脚本在每4-5天后死亡。没有hup没有捕获解释脚本突然死亡原因的日志(主要过程)。我预料到内存泄漏,并使用 top -p PID 来分析nohup进程。

随着脚本连续不断地运行, VIRT (虚拟内存)和 RES 内存大小不断增长。仅在10个小时内到达2GB左右。

基本上,一旦子线程完成作业(process-Job),即。 returns $result,那么内存应该已经发布到操作系统。

  • 我的线程实现内存是否有效?

  • 需要进行哪些更改和优化才能永久运行脚本,不会中断或无需定期重启?

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

正如评论中所提到的 - 这里没有明显的泄漏。

通过从队列中运行“worker”线程,你已经避免了一些关于线程编程的关键'陷阱'。

我建议你需要查看数据库调用和processJob子目录中创建对象的情况。 OO中的常见陷阱是在对象内创建循环引用,因此即使对象超出范围,引用计数也不会降至零。

可能值得检查是否调用了析构函数。 (http://perldoc.perl.org/perlobj.html#Destructors

DESTROY { 
    my ( $self ) = @_; 
    warn $self . " object destroyed";
}