Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TList problem Arbeitsspeicher wächst ununterbrochen (https://www.delphipraxis.net/107523-tlist-problem-arbeitsspeicher-waechst-ununterbrochen.html)

Mr.borland 29. Jan 2008 10:52


TList problem Arbeitsspeicher wächst ununterbrochen
 
hey leute, muss euch schon wieder mit einem problem auf die pelle rücken.

ich habe eine Tlist den ich zurlauf zeit immer wieder befühle und auch leere; alles funktioniert wunderbar jedoch wächst mein durch das programm belegter speicher rasant ins unermäßliche.

also ich habe dann ein test routine eingebaut und es liegt daran das Tlist, sei es durch den aufruf von clear oder Delete oder Remove den speicher nicht wieder freigibt.

Tlist löscht anscheinend nur die internen verweise ;-( sorry "habe eigentlich keine ahnung was gemacht wird" ich vermute nur.

Ich habe in meiner verzweifelung mal folgendes probiert:

1. TContainer ist von Tlist abgeleitet: das programm läuft stabil. aber der speicher wird nie freigegeben obwohl TList.count = 0 ist.

Delphi-Quellcode:
{ Clear the list by deleting all objects in it. }
procedure TContainer.ClearList;
var i:integer;
begin
    for I := (Count-1) downto 0 do begin
       Delete(i);
    end;
end;
2. TContainer ist von Tlist abgeleitet: das programm störzt unregelmäßig bei clear ab. aber der speicher wird wunderbar freigegeben.

Delphi-Quellcode:
{ Clear the list by deleting all objects in it. }
procedure TContainer.ClearList;
var i:integer;
begin
    for I := (Count-1) downto 0 do begin
       TObject(Items[I]).Free;
    end;
    inherited Clear;
end;

aber keines der lösungen ist wirklich befriedigend. ich bin dankbar für jede anmerkung, danke. Ich habe es auch mit TObjectList und TThreadList probiert, es ist immer das selbe problem.

danke für eure hilfe.

wicht 29. Jan 2008 10:59

Re: TList problem Arbeitsspeicher wächst ununterbrochen
 
Der zweite Ansatz ist richtig, weil die enthaltenen Objekte auch freigegeben werden. Ein TList.Delete() löscht nicht das, was hinter dem Zeiger steht.
Warum es da allerdings abschmiert, weiß ich nicht. Sicher, dass alle Objekte noch existieren? Wird an *keiner* anderen Stelle freigegeben? Und jedem Eintrag der Liste ist auch ein erstelltes Objekt zugeordnet worden? Ich vermute mal, da liegt der Hase im Pfeffer...

sirius 29. Jan 2008 11:01

Re: TList problem Arbeitsspeicher wächst ununterbrochen
 
1. Die zweite Variante ist richtig (je nachdem, was du in der Liste hast). Allerdings dürfte es reichen die Methode Delete zu überschreiben. (Wahrscheinlich ist eine TObjectList besser, aber das kommt auf den Kontext an)
2. Dein Fehler dürfte woanders liegen
(3. wie fühlt sich denn so eine Liste an? :mrgreen:)

shmia 29. Jan 2008 11:02

Re: TList problem Arbeitsspeicher wächst ununterbrochen
 
Hast du schon mal versucht, die Methode [TList.]Pack() aufzurufen ?
Ein TList-Objekt hat neben der Eigenschaft Count auch noch Capacity.

Bernhard Geyer 29. Jan 2008 11:05

Re: TList problem Arbeitsspeicher wächst ununterbrochen
 
Zitat:

Zitat von Mr.borland
Tlist löscht anscheinend nur die internen verweise ;-(

As Designed. TList arbeitet mit mit untypisierten Pointern und kann den "dahinterliegende" Speicher nicht freigeben da TList nicht weis was dahinterliegt.

Zitat:

Zitat von Mr.borland
2. TContainer ist von Tlist abgeleitet: das programm störzt unregelmäßig bei clear ab. aber der speicher wird wunderbar freigegeben.

Da liegt wohl der Fehler bei deinem Objekten die du in deiner Liste verwaltest. Evtl. sind hier interne verweise zwischen den Objekten vorhanden die du nicht berücksichtigst. Werden hier evtl. irgendwelche GUI-Controls freigegeben die in irgendeiner Owner/Parent-Beziehung zueinander stehen?

Mr.borland 29. Jan 2008 11:52

Re: TList problem Arbeitsspeicher wächst ununterbrochen
 
Zitat:

irgendwelche GUI-Controls freigegeben die in irgendeiner Owner/Parent-Beziehung zueinander
nein das mache ich nicht. die objekte die ich in die Liste pumpe sind Klassen wie TCircle, TLine, TBlob,TRectangle ...
also geometrische objekte. Das programm benutze ich für die Objekterkennung in der Bildverarbeitung.

Zitat:

3. wie fühlt sich denn so eine Liste an? )
ich hoffe ich habe deine frage richtig verstanden. ich mach das mit der Funktion Add...
Delphi-Quellcode:
procedure TRegionInfo.PushCircPoint(rad,x,y:Integer);
var seg : TCircle;
begin
         ...
   seg := TCircle.Create(rad,x,y);
   FCircs.Add(seg);
         ...  
end;
Zitat:

(Wahrscheinlich ist eine TObjectList besser, aber das kommt auf den Kontext an)
habe ich schon probiert, es kommen die selben probleme und fehler wie im Tlist.

RavenIV 29. Jan 2008 12:33

Re: TList problem Arbeitsspeicher wächst ununterbrochen
 
Zitat:

Zitat von Mr.borland
Zitat:

(Wahrscheinlich ist eine TObjectList besser, aber das kommt auf den Kontext an)
habe ich schon probiert, es kommen die selben probleme und fehler wie im Tlist.

Die TObjectList ist die bessere Wahl für Dich.
Jedoch müssen die Objekte beim Löschen auch hier wieder freigegeben werden.
TObjectList hat dazu eine Eigenschaft OwnsObjects. Wenn dieses auf True gesetzt wird, werden alle Objekte beim Löschen freigegeben.

marabu 29. Jan 2008 12:46

Re: TList problem Arbeitsspeicher wächst ununterbrochen
 
Hallo,

TObjectList(True) muss es sein - keine Frage. Wichtig ist dabei auch noch, dass die unterschiedlichen Objekte (Klassen) einen eigenen Destruktor besitzen, falls sie nicht nur native Datenfelder beherbergen.

Nur am Rande: Der Aufruf von Pack() bei der TList sollte nach einem Löschen mittels Clear() überflüssig sein. Nur Delete() lässt die Capacity unberührt.

Freundliche Grüße

Mr.borland 29. Jan 2008 16:27

Re: TList problem Arbeitsspeicher wächst ununterbrochen
 
hi leute,

danke für eure hilfe, again.

an schluß hat es funktioniert, und zwar mit TObjectlist. Ich fasse noch mal das wichtigste zusammen...

damit die objekte wieder freigegeben werden muß man folgendes beachten:
1.) die zu speichernden Objekte(klassen) brauchen ihr eigenen destrucktor (zu not mus man den überschreiben)
2.) Die eigenschaft OwnsObjects muß auf true gesetzt sein (ist default mäßig auch auf true)


TContainer ist von TObjectList abgeleitet...
die Elemente werden in die liste mit der TList Funktion Add ( wie gewohnlich )rein pumpt..
und so kann mann die elemente ohne rückstande wieder loswerden...
Delphi-Quellcode:
//--------------------------------------------------------------------------
{ Clear the list by deleting all objects in it. }
procedure TContainer.ClearList;
var  I: Integer;
begin
  OwnsObjects := true;
  for I := (Count-1) downto 0 do
     inherited Delete(I);

  inherited Clear; // braucht man nicht unbedingt entweder delete oder Clear reicht aus
end;
die idee, die Einzelnen Elemente TObject(Items[Index]).Free ist zwar nah an der lösung ist aber problematisch. Denn der Item counter der liste wird nicht erniedrigt. und wenn man es manuel auf 0 setzen will dann passiert etwas unerwartetes.

hofe richtig wiedergegeben zuhaben. vielen Dank für eure Hilfe.

marabu 29. Jan 2008 16:49

Re: TList problem Arbeitsspeicher wächst ununterbrochen
 
Warum führst du denn eine Methode ClearList() ein?

Die geerbte Methode Clear() sollte völlig ausreichend sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:06 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz