Newsgroup: it.comp.lang.delphi
Titolo: Memoria non rilasciata

Salve a tutti,
vi espongo il mio problema.
Ho una procedura che crea un certo numero di oggetti, dell'ordine
delle centinaia di migliaia, e
man mano che li creo, li inserisco in una lista (oggetto TList) con il
classico metodo Add().
Alla fine di tale procedura, faccio il Free di tutti gli oggetti
presenti nella lista ed eseguo il Clear.
Tale procedura si trova all'interno di un ciclo e quindi il
procedimento sopra descritto viene eseguito più volte.
Secondo logica (la mia) mi aspetterei che la quantità di memoria che
il processo impegna resti invariata dopo ogni iterazione.
E invece non è cosi: ad ogni iterazione la memoria occupata dal
processo aumenta!!!!!!!
Sono al corrente del problema di memory leak di cui soffre l'oggetto
TList.
Ho fatto tutti i controlli per vedere se non deallocavo qualche cosa
all'interno del ciclo.
Niente.
Ho provato ha settare la capacity della lista.
Ancora niente.
Ho provato ad allocare tutti gli oggetti all'inizio di ogni iterazione
e deallocarli tutti alla fine.
Di nuovo niente.
L'unica soluzione che "ho trovato" è quella di creare un numero fisso
di oggetti all'inizio e inserirli nella lista,
e ad ogni iterazione lavorare solo con quelli. Infine una volta usciti
dal ciclo, farne il Free.
In questa maniera ho visto che la memoria viene effettivamente
rilasciata dal processo (rimane ancora occupato qualche Kb).
Qualcuno conosce delle soluzioni alternative? O è l'unica soluzione?
Oppure sto sbagliando in qualche cosa?
Ringrazio anticipatamente a tutti coloro che avranno già soltanto la
pazienza di leggere questo post.

...

Ho lo stesso problema, ho una serie di frame da creare, così prima
creo uno scrollbox dove ci creo i miei frame avendo l'accortezza di
dargli come owner lo scrollbox, poi quando non mi servono più
distruggo lo scrollbox che automaticamente mi distrugge i frame
Massimo

il procedimento corretto e':
var
   i:integer;
   MyList: TList;
   c:TComponent;
begin
   MyList := TList.Create; {crea la lista}
   try
      {popola la lista}
      for i:=1 to 10 do                   {ripeti 10 volte...}
      begin
         c:=TComponent.Create(Self);    {crea un nuovo oggetto...}
         MyList.Add(c);      {...e aggiungilo alla lista}
      end;
      {rilascia _tutta_ la memoria allocata}
      while MyList.Count>0 do
      begin
         TComponent(MyList.Items[0]).Free;
         MyList.Delete(0); {questo passaggio e' importante !!}
      end;
   finally
      MyList.Free;
   end;
end;
Ciao
Duilio

end;
Se mi posso permettere, questo non è il procedimento corretto.
Funziona è vero, ma è ridondante.
TList.Delete fa, tra l'altro
 System.Move(FList^[Index + 1], FList^[Index],
      (FCount - Index) * SizeOf(Pointer));
quindi ogni volta che chiami un delete, TList deve fare un move.
Piuttosto converrebbe  iniziare dal fondo della lista fino al primo
indice, MA,  visto che alla fine del while viene fatto il free della
lista, il delete è inutile, piuttosto, se proprio devo,  meglio un
TList.Clear alla fine.
ergo:
for I := 0 to MyList.Count -1 do 
  TComponent(MyList.Items[I]).Free;
MyList..Free
Ciao.
-- 
"La velocità luce non è sufficiente Comandante Nunziatella, 
dobbiamo passare alla velocità smodata!"

MyList..Free
non dimentichi il Clear ?
for I := 0 to MyList.Count -1 do 
  TComponent(MyList.Items[I]).Free;
MyList.Clear;
MyList..Free;
AFAIK, senza il Clear, c'e' una parte di memoria che non viene
rilasciata.
"Call Clear to empty the Items array and set the Count to 0. Clear
also frees the memory used to store the Items array and sets the
Capacity to 0"
Ciao
Duilio

Massimo,
ho verificato che il Destroy di TList esegue anche il Clear, percio'
il tuo codice e' esatto e il Clear non e' necessario.
Ciao
Duilio