15

Perl が参照カウント ベースのガベージ コレクションを使用していることは知っています。変数がスコープ外になると、参照カウントが減少し、REFcount が 0 になると、メモリの割り当てが解除されます。しかし、以下に示す小さな例をトレースすると、割り当て解除が行われていることがわかりませんでした。

print "start..";

起動時のメモリ使用量

sub func
{
    my $length = 8*1024*1024;
    my $array = [1..$length];

割り当て後のメモリ使用量

}

func();

print "done..";

ガベージ コレクション ステージ中のメモリ使用量

この例では、プログラムの開始時に、Perl.exe は ~ 3 MB の物理メモリを占有します。func() 呼び出し中の割り当て後、Perl.exe は ~ 370 MB のメモリを占有します。しかし、 func() 呼び出しの後、割り当てられたメモリはガベージ コレクションされる必要があります。なぜ行われていないのですか?

返信をお待ちしております。

4

2 に答える 2

19

perlfaq3の質問「配列やハッシュを解放してプログラムを縮小するにはどうすればよいですか?」によると:

通常はできません。レキシカル (つまり、my() 変数) に割り当てられたメモリは、スコープ外に出ても、再利用または再利用できません。変数がスコープに戻った場合に備えて予約されています。グローバル変数に割り当てられたメモリは、undef() および/または delete() を使用して (プログラム内で) 再利用できます。

ほとんどのオペレーティング システムでは、プログラムに割り当てられたメモリをシステムに戻すことはできません。そのため、実行時間の長いプログラムが再実行されることがあります。一部のオペレーティング システム (特に、メモリの大きなチャンクを割り当てるために mmap(2) を使用するシステム) は、使用されなくなったメモリを回収できますが、そのようなシステムでは、perl ではなく OS の malloc を使用するように perl を構成およびコンパイルする必要があります。

一般に、メモリの割り当てと割り当て解除は、Perl ではあまり気にする必要がなく、気にする必要もありません。

Perl プログラムのメモリ使用量を減らすにはどうすればよいですか?も参照してください。

于 2013-01-04T14:54:30.097 に答える
13

Perl はメモリを解放済みとしてマークした可能性がありますが、必ずしも解放されて OS に戻されたことを意味するわけではありません。あなたの Perl プログラムはそのメモリを再利用するかもしれません。もう一度実行してみてくださいfunc。メモリの使用量が増加することはありません。

環境変数を設定して、それが違いを生むかどうかを確認したいかもしれませんPERL_DESTRUCT_LEVELが、私はそれを疑っています.

ガベージ コレクションは、Perl の最大の強みの 1 つではありません。

于 2013-01-04T15:02:44.187 に答える