Newsgroup: it.comp.lang.perl
Titolo: [RAM] Prende 70Mega!

Scusate per i continui post, perň stň impazzendo leteralmente.
Mi chiedo come puň uno scrpt di 12 Kb:
http://www.angelfire.com/droid/servlist/serverlist.txt
Prendere dopo pochi minuti ben 70mega di ram e incrementando piano piano il
file di paging.
Sembra che la sub che prenda la memoria sia questa:
sub makemet()
C'č mica una libreria che distrugga la memoria presa da questo script...
Scusate ma dopo questo affronto il perl mi ha un po' deluso, considerando
che ho provato a distruggere tutte le variabili subito dopo il loro
utilizzo.
Usato:
$var = undef;
@var=undef;
Grazie e scusate il dist.

 C'è mica una libreria che distrugga la memoria presa da questo script...
Non serve: serve piuttosto pensare le cose in un altro modo... ad esempio
invece di scrivere le linee qui sopra, potresti scrivere:
while (<FILE>){ ... }
trattando una linea alla volta invece che tutto il file in un botto.
Conclusione: posta qui le linee che ti sembra siano le responsabili del
problemazzo, e magari si trova un'alternativa.
ciao
--
perl -MLWP::Simple -e "getprint(' 
http://perl.4pro.net
 ')"

Una cosa della quale sono sicuro è che ho notato che mi prende più di dieci
mega solo quando nel file INI (che contiene le varabili per il programma,
viene attivato il controllo sui server UP).
Il controllo dei server UP lo esegui nella sub makemet() e $verifico vale 1.
Se $verifico è uguale a uno e il DNS del dominio è riuscito, prova a pingare
il server:
        if ($ip && $verifico) {
            $risp = $p->ping("$a.$b.$c.$d", $verificatimeout);
            print "$nome\t->DOWN<-\n" if ($risp == 0);
            print "$nome\t->UP<-\n" if ($risp == 1);
        }
Però ho visto che questa linea di per se non prende tanta memoria:
    my @server = <FILE>;
però seguendo il tuo consiglio la modificherò.
Riepilogo:
Lo script esegue il processo makemet() la prima volta passandogli $verifico
uguale a zero. Se la persona lo vuole può esegure nuovamente il processo
makemet con il valore $verifico=1 ed è in quel caso che ad ogni controllo
del server aumenta la memoria e non vuole saperne di liberarla.
E' un po' assurdo però...
Indirizzo del codice sorgente:
http://www.angelfire.com/droid/servlist/serverlist.txt
Grazie.

innanzi tutto, a scanso di guai, sarebbe consigliabile mettere un bel
use strict;
use warnings;
che magari ti segnala cose utili, che potrebbero essere responsabili di
tanti problemi.
Poi, un piccolo appunto tecnico/estetico... questo:
@mesi = ("Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno",
"Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre");
@giorni = ("Lunedi\'", "Martedi\'", "Mercoledi\'","Giovedi\'", "Venerdi\'",
"Sabato", "Domenica");
è più leggibile e evita errori di scrittura se magari lo scrivi così:
@mesi = qw(Gennaio Febbraio Marzo Aprile Maggio Giugno Luglio Agosto
Settembre Ottobre Novembre Dicembre);
@giorni = qw(Lunedi' Martedi' Mercoledi' Giovedi' Venerdi' Sabato Domenica);
prova con strict e warnings e facci sapere dopo le indicazioni che ti
daranno se sussiste il problema.


 
http://www.angelfire.com/droid/servlist/serverlist.txt
Una delle cose di cui ti accorgerai applicando il consiglio di
Domizio (usare strict e warnings), e` che le definizioni delle
subroutine sono sbagliate. Riporto le prime righe di makemet:
  sub makemet() {
      my $verifico = shift;
      my $savefile = "server.met";
      $savefile = "verificati.met" if ($verifico == 1);
      [...]
Scrivendo '()' dopo il nome della sub le stai assegnando un 
prototipo. In questo caso (anzi, in quasi [1] tutti i casi 
presenti nel tuo codice) il prototipo dice che la subroutine 
non accetta nessun parametro. Poi pero`
  my $verifico = shift;
il parametro viene letto. La compilazione del tuo script non
fallisce perche` le sub vengono richiamate in punti anteriori
ai luoghi in cui le sub vengono definite. Attivando gli
warning il Perl ti dira` (tra le altre cose) qualcosa di simile a:
  main::foo() called too early to check prototype at ...
Il mio consiglio e` di lasciar perdere i prototipi.
+++
Attivando strict e warnings, inoltre, il programma non compilera`
piu`: ci sono molte variabili che non sono "fully qualified", 
dichiarate con qualcosa come use vars o rese locali con my().
E` una buona occasione per rivedere/ripensare lo scope delle tue
variabili. E consiglio la lettura di "Coping with Scoping" [2].
+++
Venendo ai problemi di "elefantiasi" del programma, una volta 
applicato il consiglio di Domizio, il codice dovrebbe essere piu`
semplice e maneggevole. Ulteriore strumento di indagine e` il 
modulo Devel::Size, che ti dice l'occupazione di memoria delle
variabili:
 
http://search.cpan.org/author/DSUGAL/Devel-Size-0.54/Size.pm
(occhio alla differenza tra size e total_size)
ciao
Stefano
---
[1] A parte la sub tempo, che invece di parametri non ne usa
    proprio :))
[2] 
http://perl.plover.com/FAQs/Namespaces.html

   
http://search.cpan.org/author/DSUGAL/Devel-Size-0.54/Size.pm
Bellino!!! Non l'avevo mai visto (anche perché è piuttosto recente).
E ancora una volta... bravo Stefano, ti ribattezzerò "can da trifule" (cane
da tartufi) perché "guru" ormai non piace più a nessuno! :-)))


Stò ricontrollando tutto. Sono vicino alla soluzione.
Grazie a tutti.