1

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

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

我使用模块中的函数arena_table()Devel::Gladiator主循环中生成了一些关于arena的信息,发现typeSCALAR和的SVsGLOB在缓慢增加,导致内存使用量逐渐增加。

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,只有 type 的 SVs 在SCALAR增加,GLOBs 的数量最终会进入稳定状态。我怀疑这dclone可能会导致问题。

我的问题是,

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

0 回答 0