1

バックグラウンドで常に実行する必要がある perl スクリプトがあります。.pmいくつかのモジュール ファイルとメインファイルで構成され.plます。プログラムが行うことは、定期的にデータを収集し、計算を行い、最後にファイルに記録された結果を更新することです。

すべての重要なデータ構造は でファイル内で宣言されて.plおりour、どの.pmファイルでもパッケージ変数は宣言されていません。

arena_table()モジュール内の関数を使用Devel::Gladiatorしてメイン ループ内のアリーナに関する情報を生成したところ、タイプSCALARおよびの SV がGLOBゆっくりと増加し、メモリ使用量が徐々に増加していることがわかりました。

(タイトルを省略して再フォーマットしますarena_table。十分な時間が経過すると、最初の2つの数字だけが増加します):

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のタイプの SV のみSCALARが増加しており、 の数はGLOB最終的に安定した状態になります。dcloneここで問題が発生する可能性があるとは思えません。

私の質問は、

  1. そのモジュールによって提供される情報は正確には何を意味しますか? perldoc のステートメントは、私のような perl 初心者にとっては少しあいまいです。
  2. また、実行時間の長い perl スクリプトのメモリ使用量を減らすための一般的なスキルは何ですか?
  3. パッケージ変数がアリーナに格納されていることは知っていますが、レキシカル変数はどうですか? それらによって消費されるメモリはどのように管理されますか?
4

0 に答える 0