こんにちは、Perl 変数で大きな文字列データを扱っています (生のメール本文なので、添付ファイルを含めることができます)。Perl のsubstrに興味深い問題があります。そのリークまたは何か間違ったことをしているようです (はいの場合、何ですか?)。コードを検討してください:
#!/usr/local/bin/perl
use strict;
my $str = 'a'x10_000_000;
system("ps up $$"); #22mb used (why?)
#USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
#alt 64398 0,0 0,2 33292 22700 7 S+J 22:41 0:00,03 /usr/local/bin/perl ./t.pl
substr($str, 0, 1)='';
system("ps up $$"); #No leak
#USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
#alt 64398 0,0 0,2 33292 22732 7 S+J 22:41 0:00,04 /usr/local/bin/perl ./t.pl
substr($str, 500);
system("ps up $$"); #Leaked 10Mb (why?!)
#USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
#alt 64398 0,0 0,3 43532 32520 7 S+J 22:41 0:00,05 /usr/local/bin/perl ./t.pl
my $a = substr($str, 500);
system("ps up $$"); #Leaked 10Mb + Copyed 10Mb
#USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
#alt 64398 0,0 0,5 64012 52096 7 S+J 22:41 0:00,09 /usr/local/bin/perl ./t.pl
undef $a; #Free scalar's memory
system("ps up $$"); #Free'd 10Mb
#USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
#alt 64398 0,0 0,4 53772 42308 7 S+J 22:41 0:00,09 /usr/local/bin/perl ./t.pl
# Total leaked 2 times for 10Mb each
コマンドを見てくださいsubstr($str, 500);
。さらに、文字列の戻りコピー(それで問題ありません)、同じ量のメモリがリークするため、戻り値を2回使用すると、スクリプトが動作している間、そのうちの1つが失われます...また、そうではないようです各呼び出しがリークするため、一種の「内部バッファー」 ..
この 10Mb の増加のケースは、後続の呼び出しがますます多くのメモリを取得するため、「再利用可能な」メモリではないことに注意してください。
それを修正または回避する方法について何か提案はありますか?
私の Perl バージョン 5.14.2; 仕事で得たのと同じ動作(5.8.8)