Newsgroup: it.comp.lang.delphi
Titolo: [D5e] Bde: Insufficent memory...

Salve.
Il messaggio che ho citato in oggetto l'ho visto, da che lavoro in delphi
solo quando si interrompe la esecuzione di una app dalla ide di delphi +
volte.
Credo sia dovuto al fatto che, in questa situazione, non vengono liberate le
risorse allocate dal bde stesso.
Ma per la rima volta inizio a vedere questo msg di errore a runtime in una
mia app.
La mia app usa dei thread.
Ogni thread crea un suo oggetto tdatabase con un proprio nome, lo usa x
eseguire alcune op su un database e poi libera tutto.
Solo che dopo che la app resta in esecuzione x un bel po ho avuto questo
messaggio.
Ho controllato se avevo qualche memroy leak ma non mi sembra.
Ho trovato un errore di assegnazione che in pratica produceva il risultato
che usavo sempre una TSession creata di default dalla app e non una
specifica del thread.
Quindi adesso la situazione schematica è la seguente:
1) apro il th
2) il th crea una tSession
3) il th crea un tdatabase con nome univoco e associa alla prop sessionname
il nome della session creata al punto 2
4) creo altri oggetti che usano questo tdatabase
5) alla fine eseguo queste righe:
fDatabase.Close;
FSession.Close;
FSession.Destroy;
FDatabase.Free;
Ho trascurato qualcosa?
Bye
A.

 FDatabase.Free;
Hai provato a replicare il tutto con un solo thread utilizzando un ciclo per
creare più TSession e TDatabase?
Potresti aumentare a poco alla volta il numero di iterazioni (e quindi di
TSession e TDatabase creati) per
vedere fino a che punto ci si può spingere.
Magari memorizzi le istanze delle TSession e dei TDatabase in una
StringList.
Io sto facendo una cosa simile però, per tempo, non mi sono spinto oltre gli
11 thread.
In effetti c'è un thread principale che ne genera altri 11 che chiamano una
serie di funzioni
stipate in una dll. Una di queste funzioni, sicuramente accede ad una base
dati (con BDE) ci
fa un query banale e ritorna un risultato.
La funzione che risiede nella Dll e che viene richiamata dai thread è:
function DescriviUnita(const
IDUnita:string;Dal,Al:TDateTime;Descrizione:TStringList):boolean; stdcall;
var
    DataModule2  : TDataModule1;
begin
    Result:=bNo;
    if (IDUnita<>'') then
    begin
        if not Assigned(Descrizione) then
        begin
            MessageDlg('Lista Descrizione Unità NON
ISTANZIATA!!',mtError,[MBOK],0);
            Exit;
        end;
        try
            DataModule2:=TDataModule1.Create(Nil);
            try
                DataModule2.Database1.Open;
                DataModule2.Session1.Active:=bSi;
                DataModule2.TAnaDip.Active:=bSi;
                with DataModule2 do
                begin
                    TAnaDip.Filter:=format('[Azienda]=%s and
[Codice]=%s',[Copy(IDUnita,1,Pos('@',IDUnita)-1),Copy(IDUnita,Pos('@',IDUnit
a)+1,255)]);
                    TAnaDip.Filtered:=bSi;
                    if TAnaDip.RecordCount>0 then
                        Descrizione.Add(format('%s Matricola: %s Assunto il:
%s',[TAnaDipCognomeeNome.Value,TAnaDipMatricola.Value,TAnaDipDataassunzione.
AsString]))
                    else
                        Descrizione.Add(format('Unità %s NON
TROVATA!',[IDUnita]));
                end;
                DataModule2.TAnaDip.Active:=bNo;
                DataModule2.Session1.Active:=bNo;
                DataModule2.Database1.Close;
                Result:=bSi;
            except
                on E:Exception do
                begin
                    DataModule2.TAnaDip.Active:=bNo;
                    DataModule2.Session1.Active:=bNo;
                    DataModule2.Database1.Close;
                    Result:=bNo;
                    Descrizione.Add(format('Si è verificato un errore del
tipo: %s in **DescriviUnita**',[E.Message]));
                    raise E;
                end;
            end;
        finally
            DataModule2.Free;
            DataModule2:=Nil;
        end;
    end;
end;
Nel DataModule ho un oggetto TSession chiamato Session1.
Spero ti possa essere d'aiuto.
Saluti,
Carmine

in primis, Tnx!!! :))
me culpa, sono stato impreciso.. :((
Il mio thread ha la property AutoTerminate a True.
Una volta fatto cio che deve fare, libera gli oggetti e si autodistrugge.
Quindi, il numero max di th in esecuzione è sempre limitato anche x il tempo
per la sua esecuzione è rapidissimo al punto da non essere quasi misurabile.
Qui di seguti la seuenza giusta
1) apro il th che riceve in ingresso una serie di richieste da processare
2) il th crea una tSession
3) il th crea un tdatabase con nome univoco e associa alla prop sessionname
il nome della session creata al punto 2
4) creo un oggetto per ogmi richiesta ricevuta



Dico una fesseria, sei pronto? :) Sicuro? ok...
Perchè non ti crei una coppia di componenti:
TMySession e TMyDatabase
e modifichi i loro costruttori/distruttori, in maniera tale da implementare
un
reference counting? Magari ci piazzi qualche messaggio di debug
per vedere se da qualche parte qualcuno/qualcosa richiama un
costruttore/distruttore?
Magari, giusto per crearsi qualche altro casino, perchè non crei un thread
"monitor" che
fornisca informazioni sul reference counting di cui sopra e, magari, anche
una
descrizione delle risorse occupate?
L'ho sparata troppo grossa? Uhmm, a mia discolpa dico che, ad occhio, non
riesco
a trovare dove possa esserci l'inghippo.
Nel senso che dato per certo quanto segue:
Punto 4)
    - siamo sicuri che gli oggetti (Session e DB) siano stati istanziati
correttamente.
    - siamo sicuri che nessuna operazione esplicita/implicita richiami un
costruttore che:
      4.1) Possa sovrascrivere il contenuto della variabile che contiene
l'istanza originaria di Session e/o DB.
Punto 5)
    - siamo sicuri che si tratta dell'ultima serie di operazioni che compi
su Session e DB
Non riesco ad intuire altri meandri in cui infilarci un bel "bug o feature"
:)
Fammi sapere. Saluti

 Non riesco ad intuire altri meandri in cui infilarci un bel "bug o
feature"
Tnx di tutto, Carminie'!
Mismazzo&tiaggiorno
A.