Ho un lungo script perl che memorizza alcune informazioni da un file in un hash, e ogni tanto (qui, ogni 100000 posizioni), stampa i valori dell'hash per quella finestra, quindi tenta per eliminare la maggior parte dei contenuti dall'hash, ad eccezione di un piccolo buffer da utilizzare nella successiva iterazione.memoria perl gonfia in hash anche quando si esegue l'eliminazione?
Dico che tenta di eliminare il contenuto, perché il mio script fa esplodere in memoria, fino a quando non utilizza tutta la memoria e si blocca. Anche se è sembra che l'istruzione di cancellazione riduca il numero di chiavi nell'hash (vedi STDERR di stampa di seguito) solo su un numero ridotto di elementi, il consumo di memoria dello script è pari a come se non stia cancellando il contenuto di . Se commento l'istruzione delete, utilizza la stessa quantità di memoria dello , con l'unica differenza che richiede più tempo per iterare . Sembra che il numero di chiavi sia ridotto dopo il comando di cancellazione , ma non il numero di valori.
Mi sono assicurato che non ci fosse buffering strano con la lettura e l'emissione di risultati. In effetti, lo script non esaurisce la memoria se Mi limito a commentare i luoghi in cui viene utilizzato% hash, quindi l'ho ristretto a fino al riempimento e all'eliminazione delle voci in% hash.
Ho anche provato a utilizzare un hashref anziché% hash e lo stesso è ancora .
Come mai si sta facendo esplodere nella memoria? Mi manca qualcosa di ovvio qui?
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);
}
#}
uscita è qualcosa di simile:
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
[...]
Questo sta usando v5.14.2 perl su una scatola a 64 bit di Linux.
Quando si eliminano elementi di un hash, sembra che i bucket allocati non vengano ripristinati. 'perl -le '$ min = 0; $ max = maiusc; % a = mappa $ _ => 1, $ min .. $ max; per (1 .. $ max - 10) {cancella $ a {$ _}}; print scalar% a '1000001' Output: '5/524288' Prova a copiare la chiave/i valori. – TLP
@TLP copia la chiave/i valori? – 719016
crea un nuovo hash copiando quello vecchio e lascia che il vecchio esca dallo scope – mirod