Perl:Devel :: Gladiator模块和内存管理

时间:2013-05-17 03:57:53

标签: perl memory-management

我有一个需要在后台不断运行的perl脚本。它由几个.pm模块文件和一个主.pl文件组成。该程序的作用是定期收集一些数据,进行一些计算,最后更新记录在文件中的结果。

所有关键数据结构都在.pl文件中使用our声明,并且在任何.pm文件中都没有声明包变量。

我使用arena_table()模块中的函数Devel::Gladiator来生成主循环中有关竞技场的一些信息,并发现SCALARGLOB类型的SV正在缓慢增加,导致内存使用量逐渐增加。

arena_table的输出(我重新格式化它们,省略标题。经过足够长的时间后,只有前两个数字增加):

2013-05-17@11:24:34  36235 3924 3661 3642 3376 2401 720 201 27 23 18 13 13 10 2 2 1 1 1 1 1 1 1 1 1 1

跑了一段时间后:

2013-05-17@12:05:10  50702 46169 36910 4151 3995 3924 2401 720 274 201 26 23 18 13 13 10 2 2 1 1 1 1 1 1 1 1 1

主循环类似于:

our %hash1 = ();
our %hash2 = ();
# and some more package variables ...
# all are hashes

do {
    my $nowtime = time();
    collect_data($nowtime);
    if (calculate() == 1) {
        update();
    }   
    sleep 1;
    get_mem_objects(); # calls arena_table()
} while (1);

get_mem_objects除外,其他函数将对our声明的全局哈希值进行操作。在update中,程序将进行一些日志轮换,代码如下:

sub rotate_history() {
    my $i = $main::HISTORY{'count'};
    if ($i == $main::CONFIG{'times'}{'total'}) {
        for ($i--; $i >= 1; $i--) {
           $main::HISTORY{'data'}{$i} = dclone($main::HISTORY{'data'}{$i-1});
        }
    } else {
        for (; $i >= 1; $i--) {
           $main::HISTORY{'data'}{$i} = dclone($main::HISTORY{'data'}{$i-1});
        }
    }

    $main::HISTORY{'data'}{'0'} = dclone(\%main::COLLECT);

    if ($main::HISTORY{'count'} < $main::CONFIG{'times'}{'total'}) {
        $main::HISTORY{'count'}++;
    }
}

如果我评论对此函数的调用,在Devel::Gladiator给出的最终报告中,只有SCALAR类型的SV正在增加,GLOB的数量最终会进入稳定的状态。我怀疑dclone可能会导致此问题。

我的问题是,

  1. 该模块提供的信息究竟是什么意思?对于像我这样的perl新手来说,perldoc中的陈述有点模糊。
  2. 并且,降低长时间运行的perl脚本的内存使用率的常用技巧是什么?
  3. 我知道包变量存储在竞技场中,但词法变量怎么样?他们如何管理所消耗的内存?

0 个答案:

没有答案