3

Perl でこのリークが発生するのはなぜですか?

$ perl -MDevel::LeakTrace::Fast -e 'our @a=(1);our @b=(1)'
leaked SV(0x0x84e053c) from -e line 1

$ perl -v
This is perl, v5.8.0 built for i386-linux-thread-multi
[...]

$ uname -a
Linux ant1 2.4.21-20.ELsmp #1 SMP Wed Aug 18 20:46:40 EDT 2004 i686 i686 i386 GNU/Linux   

ありがとう!

4

1 に答える 1

10

そうではありません。ループに入れて、自分の目で確かめてください。プロセス メモリは、ループの反復ごとに増加しません。

for(1 .. 10_000_000)
{
  our @a = (1);
  our @b = (1);
}

その「リーク」メッセージはすべて、(おそらく) プログラムが未処理の変数で終了したことを示しています。そのメッセージを黙らせるには、プログラムの終了前に変数を定義解除します。

perl -MDevel::LeakTrace::Fast -e 'our @a = (1); our @b = (1); undef @a; undef @b;'

FWIW、同じメッセージが perl 5.10.0 で出力されるため、perl をアップグレードすることが答えであるかどうかはわかりません。

メッセージが表示される場合と表示されない場合がある理由については、おそらく Devel::LeakTrace::Fast の気まぐれです。多くの Perl リーク検出モジュールには、このような「特異性」(親切に言えば) があります。

結論: リークをテストする 100% 信頼できる唯一の方法は、問題のコードを繰り返し実行してメモリ使用量が増加するかどうかを確認することです。疑わしいときは、それに立ち返ってください。

ただし、さまざまな Devel::* モジュールが役立ちます。ただし、最初にリークしているコードを分離するのが最善です。コードの半分を無効にして、リークが続くかどうかを確認します。これで、検索を半分に絞り込みました。数回繰り返すと、リークしている関数またはステートメントにすぐにたどり着きます。次に、そのコードを別のスクリプトに入れたときにまだリークするかどうかを確認します。最後に、リークの原因を確認するには、Devel:: モジュールを使用します (たとえば、Devel::Cycleを使用してメモリ サイクルをチェックします)。

于 2008-11-17T18:21:18.337 に答える