简体   繁体   English

perl DBI内存泄漏

[英]perl DBI memory leak

I'm having some memory leak issues in a perl script that I'm running for extended periods of time, where the amount of memory that perl is taking up just continues to grow. 我在长时间运行的perl脚本中遇到一些内存泄漏问题,其中perl占用的内存量持续增长。 Because of this, I am trying to use Devel::Leak to track down the leak. 因此,我正在尝试使用Devel :: Leak跟踪泄漏。 I discovered that whenever I call DBI 's prepare method, the number of scalar values returned by Devel::Leak goes up by one. 我发现,每当调用DBIprepare方法时, Devel::Leak返回的标量值的数量就会增加一。 Below is I test script I've put together that does what I'm describing: 下面是我测试过的脚本,它们可以完成我正在描述的事情:

#!/usr/bin/perl
use strict;
use Devel::Leak;
use DBI;

START:
my $handle; # apparently this doesn't need to be anything at all
my $leaveCount = 0;
my $enterCount = Devel::Leak::NoteSV($handle);
print "ENTER: $enterCount SVs\n";
{
    # CONFIG VARIABLES
    my $platform = "mysql";
    my $database = "db";
    my $host = "localhost";
    my $port = "3306";
    my $user = "user";
    my $pw = "pass";

    #DATA SOURCE NAME
    my $dsn = "dbi:mysql:$database:$host:3306";

    # PERL DBI CONNECT
    my $dbh = DBI->connect($dsn, $user, $pw);
    $dbh->prepare("SELECT * FROM table"); # The script seems to gain one SV without this
                                          # line here, but since this is my issue in my
                                          # main script I decided to leave it in
    # undef $dbh; I tried undef-ing this, but it made no difference
}
$leaveCount = Devel::Leak::CheckSV($handle);
print "\nLEAVE: $leaveCount SVs\n";
sleep(1);
goto START;

So is there something I'm doing wrong here, or is this a memory leak in the DBI module? 那么我在这里做错什么了吗,或者这是DBI模块中的内存泄漏? Also, I know that adding one SV every time around the loop isn't a huge deal, and that I most likely have larger memory leaks elsewhere that are causing perl to take so much of the server's memory. 另外,我知道每次在循环中添加一个SV都不是一件大事,而且我很可能在其他地方出现更大的内存泄漏,这导致perl占用了服务器的大量内存。 However, I'd still like to fix this if I could. 但是,如果可以的话,我仍然想解决此问题。 Coder's curiosity :) 程序员的好奇心:)

UPDATE: 更新:

The first time through it seems to add about 3,000 SV's, and then every time after that it goes up 1 at a time. 第一次通过它似乎增加了大约3,000 SV,然后每次之后每次都增加1。

There is a instance of DBI::dr (a blessed hash) living at $DBI::lasth. $ DBI :: lasth上有一个DBI :: dr(祝福的哈希)实例。 Check out the ChildHandles key. 签出ChildHandles键。

#!/usr/bin/perl

use strict;
use warnings;
use Devel::Leak;
use Data::Dumper;
use Symbol::Table;
use DBI;

START:
{
    my $handle;
    my $enterCount = Devel::Leak::NoteSV($handle);

    DB:
    {
        my $platform = "mysql";
        my $database = "db";
        my $host     = "localhost";
        my $port     = "3306";
        my $user     = "user";
        my $pw       = "pass";

        my $dsn = "dbi:mysql:$database:$host:3306";

        my $dbh = DBI->connect( $dsn, $user, $pw );

        $dbh->prepare("SELECT * FROM table");

        $dbh->disconnect();
    }

    my $st = Symbol::Table->New( 'SCALAR', 'DBI' );

    for my $subpkg ( keys %{ $st } ) {

        my $val;
        {
            my $var = "DBI::${subpkg}";
            no strict 'refs';
            $val = ${$var};
        }

        print "scalar '$subpkg' => '$val'\n";
    }

    print Dumper( $DBI::lasth );

    $DBI::lasth->{ChildHandles} = []; # <-- reset leaking data structure

    my $leaveCount = Devel::Leak::CheckSV($handle);

    print "\nCOUNT: $enterCount to $leaveCount SVs\n";

    sleep(1);

    redo START;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM