私は、ファイル からいくつかの情報をキャッシュに入れた長いperlスクリプトを持っています。そして、たびに(ここでは、100000の位置ごとに)、 はそのウィンドウのハッシュの値を表示し、 には、次の反復で使用される小さなバッファ を除いて、ほとんどのコンテンツがハッシュから削除されます。削除してもペールメモリがハッシュで膨らんでいますか?
すべてのメモリとクラッシュが使用されるまで、私のスクリプトはメモリ使用量が であるため、内容を削除しようとしています。それ は、それが 内容を削除されていないかのようにdelete文は、要素のほんの数、スクリプト急騰の メモリ消費に(下の印刷STDERRを参照)ハッシュ 内のキーの数を減らしていると思われるにもかかわらず。私がdeleteステートメントをコメントアウトすると、同じ の量のメモリが使用されますが、唯一の違いは になります。 コマンドの削除後にキーの数が減少したように見えますが、値の数は減少していません。
私は読みとりに奇妙なバッファリングがなく、結果が であることを確認しました。実際には、スクリプトではメモリが不足しています。 %hashが使用されている場所をコメントアウトしているだけなので、%hashのエントリの埋め込みと削除まで を絞り込みました。
また、%hashの代わりにhashrefを使用しようとしましたが、同じことがまだ起こっています が起こっています。
どのようにメモリに爆発していますか?私は何も明らかでないのですか ここですか?
my %hash;
# while (Read from input) {
# Fill hash here and there with: $hash{$this_p}{$this_c}++
# ...
# Then every 100000 entries
if (not $pos % 100000) {
print STDERR "pre ", scalar %hash , "\n";
warn total_size(\%hash);
for my $p (sort { $a <=> $b } keys %hash) {
last if ($p > $max_possible{$subset});
if ($p + $buffer < $pos) {
print $out "$p\t";
for my $c (keys %{ $hash{$p} }) {
print $out "$c ". $hash{$p}{$c} . ";";
}
print $out "\n";
delete $hash{$p};
}
}
print STDERR "post ", scalar %hash , "\n";
warn total_size(\%hash);
}
#}
出力は次のようなものである:これは64ビットのLinuxボックス上のperl v5.14.2を使用している
pre 322484/524288
134297952 at /home/
post 681/524288
4368924 at /home/av
pre 681/524288
4368924 at /home/av
post 681/524288
4368924 at /home/av
pre 681/524288
4368924 at /home/av
post 681/524288
4368924 at /home/av
pre 629257/1048576
260016542 at /home/
post 344/1048576
8477509 at /home/av
pre 1903885/4194304
689633878 at /home/
post 900/4194304
33790436 at /home/a
[...]
。
ハッシュの要素を削除すると、割り当てられたバケットがリセットされていないようです。 'perl -le '$ min = 0; $ max = shift; %a = map $ _ => 1、$ min .. $ max; for(1 .. $ max - 10){delete $ a {$ _}};スカラーを出力する%a '1000001'出力: '5/524288'代わりにキー/値をコピーしてみてください。 – TLP
@TLPキー/値をコピーしていますか? – 719016
古いものをコピーして新しいハッシュを作成し、古いものを範囲外にします。 – mirod