Newsgroup: it.comp.lang.delphi
Titolo: ReportMemoryLeaksOnShutdown

Seguendo il consiglio di Davide, ho inserito la istruzione in oggetto a true 
nel mio progetto e in effetti ricevo tante segnalazioni di leak, che però 
non so interpretare. Magari potete aiutarmi. Per esempio, ho ricompilato per 
correggere un bug e adesso ho ricevuto le seguenti:
1-12 bytes: String x 1
53-60 bytes: TStringList x 2
1373-1500 bytes: Unknown x 1 
 


Significa che alcuni oggetti sono stati creati (o aree di memoria sono state
allocate) senza che sia avvenuta la corrispondente distruzione.
 
Ignora per il momento prima e terza segnalazione e concentrati sulla
seconda riga: in pratica ti sta dicendo che hai due oggetti TStringList
creati e mai distrutti. Devi controllare il tuo codice per capire
dove possono essere queste "mancate distruzioni" che ti segnala.
 
Per avere informazioni aggiuntive occorrono strumenti piu' avanzati,
questo e' proprio il minimo sindacale... :-)
 
Poi considera che questa operazione e' completamente a run-time, dipende
dal codice che fai eseguire al programma, da quali finestre apri, che
pulsanti premi eccetera, non fa un controllo statico del tuo sorgente.
 
 
ciao
Giacomo

Citi degli strumenti più avanzati, ne puoi citare qualcuno ?
Intanto grazie 
 

 Intanto grazie
 
Cosi' sui due piedi ti direi AQTime ed Eurekalog. Purtroppo non sono
gratis...
 
ciao
Giacomo

Ciao,
come ti hanno gia' detto hai degli oggetti non liberati.
 
Se puo' esserti utile ogni volta che crei un oggetto, subito dopo 
distruggilo cosi' non lo dimentichi.
Successivamente, in mezzo metti tutto cio' serve.
Esempio
 
1)
Procedure Test
Begin
 
End;
 
2)
Procedure test
Var LST : TStringList;
Begin
    LST:=TStringList.Create;
 
    Freeandnil(LST); // Cosi' non lo dimentichi
end;
 
3)
Procedure test
Var LST : TStringList;
Begin
    LST:=TStringList.Create;
     // Adesso qui metti il codice ...
    Freeandnil(LST);
end;
 
Vedrai che poi, per questi casi, non avrai piu' dimenticanze in giro.
 
Come strumento avanzato io uso EurekaLog, caro ma decisamente valido.
 
Ciao
 
Daniele 
 

Grazie. Sono andato a vedere EurekaLog e costa 150 euro nella versione meno 
cara. Volevo scaricare la versione trial, ma poi non l'ho fatta perchè dice 
che il progetto su cui si usa scade dopo 30 giorni. Ho capito bene ? E se 
decido di non comprarlo ? E poi non potrei applicarlo su una copia del 
progetto ? Cs'è che non capisco ?o 
 

Ciao,

Dipende da quello che devi/vuoi fare.
I miei lavori sono per uso personale (nel senso che vengono utilizzati 
all'interno della nostra ditta), quindi la versione acquistata la piu' 
completa.
Se i tuoi lavori NON sono impiegati in un contesto "lavorativo" eurka log e' 
troppo e puoi tranquillamente usare degli strumenti piu' leggeri e gratuiti 
(vedi torry).
Poi e' possibile che certi programmi gratuiti siano piu' performanti di 
quelli commerciali .... ma e' un'altra storia.
Se invece il tuo lavoro e' utilizzato anche in ambito lavorativo, allora 
devi utilizzare uno strumento il piu' completo possibile.
 
Tornando ad eureka log, la versione dimostrativa funziona al 100%.
Dopo 30 giorni la tua applicazione NON viene piu' compilata (o meglio e' 
compilata ma NON viene eseguita) ma nelle impostazioni puoi sempre 
disattivare il controllo di eureka log o, in caso estremo, lo puoi sempre 
disinstallare.
Io lo sto usando dal lontano delphi 6.0.
Devi considerare se la spesa vale il tempo che puoi risparmiare nel cercare 
i problemi (questo vale per tutte le librerie per esempio TMS o DevExpress, 
io gia' da anni mi sono appoggiato a tms).
 
Alla prossima
 
Ciao
 
Daniele 
 

 Vedrai che poi, per questi casi, non avrai piu' dimenticanze in giro.
 
Se poi vuoi anche assicurarti che distrugga sempre tutti gli oggetti
creati, anche in caso di errori, ci metti un bel try..finally :
 
Procedure test
Var LST : TStringList;
Begin
  LST:=TStringList.Create;
  TRY
     // Adesso qui metti il codice ...
  FINALLY 
    Freeandnil(LST);
  END; 
end;
 
ciao
Giacomo

"Giacomo Degli Esposti"  ha scritto nel messaggio 
news:c2e101ac-68f1-4c26...@googlegroups.com...
Se poi vuoi anche assicurarti che distrugga sempre tutti gli oggetti
creati, anche in caso di errori, ci metti un bel try..finally :
 
Procedure test
Var LST : TStringList;
Begin
  LST:=TStringList.Create;
  TRY
     // Adesso qui metti il codice ...
  FINALLY
    Freeandnil(LST);
  END;
end;
ciao
Giacomo
....
Si, questo ormai ho imparato a farlo sempre, ma non so se io sono un caso 
speciale, ma mi capita quasi sempre che se creo una StringList (o una 
ObjectList e altro), la creo perchè devo usarla un pò dappertutto nella mia 
applicazione e quindi non mi trovo quasi mai nella condizione di crearla e 
poterla distruggere nell'ambito di una stessa proc.
Non capita anche a voi questo ? 
 

 Non capita anche a voi questo ?
 
A me ... onestamente no !!
Tutto quello che ti serve e', di norma, nel data base quindi al bisogno crei 
una lista e quando non serve piu' (in quel contesto) la liberi.
Comunque non e' errato crearti una lista globale da utilizzarsi in giro per 
le unti.
Nella main form, o dove credi, alla INIZIALIZZAZIONE la crei e quando chiudi 
il programma la LIBERI.
In questo contesto hai da gestire una gran serie di casistiche.
La devi aggiornare ogni volta che lavori sul db, devi posizionare il cursore 
a dovere ecc... ecc...
Ovvero la lista deve seguire tutti i cambiamenti che operi sul db.
Infine, da non trascurare, in fase di debug una variabile locale e' piu' 
gestibile di una globale.
Il dato locale e' di immediato conrtrollo, quella globale ti devi ricordare 
DOVE hai settato il dato che potrebbe darti problemi.
 
Infine, a titolo personale, io come variabili globali tendevo ad impostare 
quei valori impostati da configurazione (percorsi, numeri, colori ecc...) 
che prima venivano registrati in un file .ini
Poi, essendo passato ad un record di configurazione, ho tolto anche quelle 
perche' utilizzo il record di configurazione, per esempio
 
If  MaxBackUp>TabellaConfigurazione.FieldbyName('MaxBackUp').AsIntegr then 
fai_quello_che_devi
 
Ciao
 
Daniele
 
 

A me ... onestamente no !!
Daniele
....
E io lo trovo molto strano. Ti faccio degli esempi su una applicazione di 
contabilità. In quasi tutti i form all'utente è data la possibilità di 
scegliere da una Lista di conti, da una Lista di Centri di Costo, da una 
lista di anni e mi fermo qui.
Quasi sempre creo delle liste di tipo TList (se devo memorizzare gli oggetti 
Conto, con tutti i loro dati), oppure delle StringList (nella maggioranza 
dei casi), con le quali nelle varie unit creo ComboBox oppure ListBox etc.
Quindi tutte queste liste non le creo e libero, ma le crea il Main che 
controlla tutte le altre unit e le libera alla fine.
Quale alternativa avrei ?
Quella di crearle quando l'utente entra nel form che le usa, nel quale egli 
può entrare e uscire enne volte e quindi le liste (o direttamente i combo, 
listbox etc.) andrebbero ricreate enne volte.
Poichè la fonte dei dati sono sempre dei dataset da scandire o sui quali 
operare delle query, non è uno spreco di tempo e risorse ? . Non è meglio 
farlo una volta per tutte ? Si, è vero, in alcuni casi devo controllare le 
modifiche che possono determinare comunque che una particolare lista vada 
ricreata..
Bada bene che non sto per niente obiettando ai tuoi commenti. L'intento 
delle mie considerazioni è che nello scambio di opinioni cerco di carpire 
quante più cose è possibile..
 
 
 
 

 quante più cose è possibile..
Non e' chi ha ragione o torto ma di come si e' organizzati.
Se ti trovi bene cosi', non vedo il perche' tu debba cambiare qualcosa.
 
A questo proposito sarebbe interessante sapere anche gli altri come 
approcciano questo argomento!!!
 
Ciao
 
Daniele
 
 
 

 non controlli nulla.
 
Non e' proprio cosi'... anche se esteticamente sembra piu' 
gradevole, mettere il Create dentro al TRY e' sbagliato: in 
caso di errore nel costruttore, il free contenuto nel finally 
verrebbe eseguito su un oggetto non correttamente costruito. Questo
puo' produrre errori non prevedibili a priori ed e' comunque male.
Il Create va messo fuori dal try, anche se e' meno bello a vedersi.
 
A riprova di questo, puoi controllare tutti i sorgenti della
VCL e i sorgenti scritti da gente piu' esperta di me e te e vedrai 
che i Create sono sempre fuori dal try.
 
ciao
Giacomo

 scritti da gente piu' esperta di me e te 
Di te non so .... di me ... certamente SI !!!
 
Grazie
 
Ciao
 
Daniele

 Il Create va messo fuori dal try, anche se e' meno bello a vedersi.
 
Non č proprio cosě... Anche io metto i create fuori dal costrutto try/finally, 
ma dai un'occhiata all'articolo sul blog di Marco Cantů:
 
http://feedproxy.google.com/~r/marcocantublog/~3/42VOmXKgKLg/2018-january-multiple-try-finally-delphi.html
 
 
Le tre soluzioni finali sono tutte corrette e la #2 e la #3 hanno il Create 
dopo il try.
 
HTH,
David
 
 

Per completezza: 
 
Ad essere onesto la soluzione #2 non mi piace, ma trovo molto interessante 
la #3.
 
David
 
 

 applicarlo su una copia del progetto ? Cs'è che non capisco ?o
 
Aumenta la fattura del costo del componente e compratelo.
Fine dei problemi.
 
-- 
Morde