Ich bin jetzt ein kleines Stück weiter. Habe mal alles deaktiviert, alle Threads, so dass am Ende nur der Mainthread über bleibt. Sprich die
DB wird geöffnet und bei Programmende wieder geschlossen, ohne dass
DB-Abfragen dazwischen laufen. Ergebnis: Keine MemoryLeaks.
Jetzt fange ich an, alles Stück für Stück wieder zu aktivieren, und teste jedes Mal ob und wo ein MemoryLeak auftritt.
Ich bin auch gleich fündig geworden in folgende Methode:
Delphi-Quellcode:
procedure TStamminfos.LoadFromDBByRev(Con: TUniConnection; Betriebguid,
Refguid: TGUID; Ref:
string);
var
q: TUniQuery;
begin
q:=TUniQuery.Create(
nil);
try
q.Connection:=Con;
if not Con.Connected
then exit;
q.SQL.Text:='
Select * from stamminfos where betriebguid=:betriebguid and (Refguid=:refguid or ref=:ref)';
q.Params.ParamValues['
betriebguid']:=Betriebguid.ToString;
q.Params.ParamValues['
Refguid']:=Refguid.ToString;
q.Params.ParamValues['
Ref']:=Ref;
q.Active:=True;
if q.RecordCount>0
then
begin
Self.ID:=q.FieldByName('
ID').AsInteger;
Self.guid:=StringToGUID(q.FieldByName('
guid').AsString);
Self.betriebguid:=StringToGUID(q.FieldByName('
betriebguid').AsString);
Self.Refguid:=StringToGUID(q.FieldByName('
Refguid').AsString);
Self.Ref:=q.FieldByName('
Ref').AsString;
Self.RTFText.Position:=0;
(q.FieldByName('
RTFText')
as TBlobField).SaveToStream(Self.RTFText);
//<<--Hier muss der Übeltäter liefen.
Self.RTFText.Position:=0;
Self.Text:=q.FieldByName('
Text').AsString;
Self.Level:=TInfosLevel(q.FieldByName('
Level').AsInteger);
end;
q.active:=False
finally
q.Free;
end;
end;
Kommentiere ich die Zeile SaveToStream aus, so habe ich kein MemoryLeak. Lass ich sie mit ausführe, habe ich ein MemoryLeak.
Ist das Auslesen eines BlobFields denn so falsch? (Self.RTFText ist TMemoryStream, welches auch korrekt erzeugt und freigegeben wird).
Gibt es noch eine andere (bessere) Möglichkeit den Inhalt von BlobFiels auszulesen? Ich kenn nur die.
PS: Die o.g. Methode läuft in einem Thread, der seine eigene Connection hat.