Delphi-PRAXiS
Seite 5 von 6   « Erste     345 6      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Nodes einer VirtualStringTree hinzufügen - aber schneller! (https://www.delphipraxis.net/190454-nodes-einer-virtualstringtree-hinzufuegen-aber-schneller.html)

Jim Carrey 6. Okt 2016 15:18

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
 
Aber zur Theorie.. woran könnte es gelegen haben, dass der Speicher vorher nicht wieder freigegeben wurde obwohl doch die Knoten mit .Free alle einzeln aufgerufen wurden?
Ich habe sogar zum Test beim Hinzufügen der Knoten jeden einzelnen validieren lassen aber auch das half nichts.

Aviator 6. Okt 2016 15:25

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
 
Zitat:

Zitat von Jim Carrey (Beitrag 1350014)
Aber zur Theorie.. woran könnte es gelegen haben, dass der Speicher vorher nicht wieder freigegeben wurde obwohl doch die Knoten mit .Free alle einzeln aufgerufen wurden?
Ich habe sogar zum Test beim Hinzufügen der Knoten jeden einzelnen validieren lassen aber auch das half nichts.

Ohne SourceCode ist das reine Spekulation. Wenn du den noch hast, dann stell ihn mal hier rein. Bei Gelegenheit schau ich (oder die anderen) dann mal drüber. Wird ja nichts extrem kompliziertes sein denke ich.

Die andere Frage wäre jetzt, ob das nicht egal ist. Es läuft ja jetzt. ReportMemoryLeaksOnShutdown gibt dir auch keine Meldung aus? Wenn nicht, dann ist alles gut.

Und beachte auch noch Post #36 von Daniel bzgl. des Speicherverbrauchs einer Anwendung. Wenn du da genaueres wissen willst, dann solltest du dir evtl. den ProcessMonitor anschauen. Der müsste das genauer darstellen. Aber da ist jaenicke der Profi drin. Mit dem kenne ich mich nicht so gut aus.

Jim Carrey 6. Okt 2016 15:36

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
 
Den Code habe ich leider nicht mehr.

Zitat:

Die andere Frage wäre jetzt, ob das nicht egal ist. Es läuft ja jetzt. ReportMemoryLeaksOnShutdown gibt dir auch keine Meldung aus? Wenn nicht, dann ist alles gut.
Nicht ganz.
Ich erstelle in meiner Schleife für jeden Knoten den ich zur VST hinzufüge parallel einen eigenständigen Datensatz. Das will ich irgendwann einmal ändern aber nicht jetzt.

Früher benutze ich ein Record. Da stehen ein paar Strings, Booleans und Integers drin. Später habe ich daraus Class gemacht, da ich diese Klassen-Instanz dann einer ObjectList hinzufüge, welche später benötigt wird.

Delphi-Quellcode:
Datensatz := TMeinDatenSatz.Create;
DatenSatz.MeinString := '123';
MeineObjektListe.Add(DatenSatz); // Liste hat OwnsObjects auf False, da das sonst Fehler gibt
Nun gehe ich diese Liste durch und gebe alles frei:
Delphi-Quellcode:
for i := MeineObjektListe.Count - 1 downto 0 do
 begin
  TMeinDatenSatz(MeineObjektListe.Items[i]).Free;
  MeineObjektListe.Delete(i);
 end;

 MeineObjektListe.Free;
Beim Beenden des Programms dann die Meldung, dass dutzende Unicode-Strings nicht freigegeben wurden. Das sind zu 100% die aus TMeinDatenSatz.

Aviator 6. Okt 2016 15:47

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
 
Wie erzeugst du deine ObjectList?

Wenn du folgendes machst, dann brauchst du gar nichts freizugeben. Das macht die Liste dann für dich. Anders sieht es aus wenn du dem Constructor als Parameter ein False mitgibst.

Delphi-Quellcode:
procedure CreateList();
begin
  MeineObjektListe := TObjectList.Create(); // Create hat einen optionalen Boolean Parameter OwnsObjects der standardmäßig true ist
end;


procedure FreeList();
begin
  MeineObjektListe.Free; // Sofern OwnsObjects auf true steht, werden hier alle enthaltenen Objekte automatisch freigegeben
end;
Wie sieht denn deine
Delphi-Quellcode:
TMeinDatensatz
Klasse aus? Wird dort denn im Destructor immer alles schön freigegeben?

Jim Carrey 6. Okt 2016 15:52

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
 
OwnsObjects habe ich auf False, da es sonst Probleme gibt.

Ich habe eine ObjectList mit allen Informationen drin und diese ObjectList teile ich auf weitere ObjectListen auf. Deswegen muss es False sein.

Aviator 6. Okt 2016 16:01

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
 
Sorry. Hatte den Kommentar übersehen. In dem Fall wäre der SourceCode deiner erzeugten Klasse hilfreich. Ich befürchte aber das da irgendwas beim Verschieben der Objekte in eine andere Liste passiert.

Jim Carrey 6. Okt 2016 16:09

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
 
Zitat:

Ich befürchte aber das da irgendwas beim Verschieben der Objekte in eine andere Liste passiert.
Ich hatte mich versehentlich falsch ausgedrückt!

Der ObjectList-Schnick-Schnack wird gar nicht ausgeführt aktuell. Daran liegt es nicht. Sorry.

Meine Klassen-Instanzen erzeuge ich wie oben bereits geschrieben.
Delphi-Quellcode:
type
 TMeinDatenSatz = class

 private
  FIrgendeinString: String;
  FIrgendeinBoolean: Boolean;
 public
  property IrgendeinString: String read FIrgendeinString write FIrgendeinString;
  property IrgendeinBoolean: Boolean read FIrgendeinBoolean write FIrgendeinBoolean;
 end;

/////////////////////////////////////////////////////////////////////////////////////////////

MeinDatenSatz := TMeinDatenSatz.Create;
TMeinDatenSatz.IrgendeinString := 'ABC';
TMeinDatenSatz.IrgendeinBoolean := False;
MeineObjectList.Add(TMeinDatenSatz);

/////////////////////////////////////////////////////////////////////////////////////////////

for i := MeineObjectList.Count - 1 downto 0 do
 begin
  TMeinDatenSatz(MeineObjectList.Items[i]).Free;
  MeineObjectList.Delete(i);
 end;

MeineObjectList.Free;
Das hier ist eine 1-zu-1-Übertragung nur mit geänderten Variablen-Namen, um es einfacher zu halten.

Ich sehe gerade lustigerweise, dass der Leak nur auftritt, wenn es Knoten in meiner VST gab die nicht sichtbar waren (also Scrollbar war da).
Wenn diese zu lange VST aber einmal alle Knoten angezeigt hat, gibt es den Leak trotzdem.

Wenn die VST nur 10 Knoten enthielt und alle sofort bei FormShow sichtbar waren, gab es den Leak nicht.
Wenn ich bei den 10 Knoten das Fenster verkleinere und bei FormShow nicht alle angezeigt werden, gibt es den Leak -nicht-.
Scheint also ein "Problem mit Massen" zu sein.

Aviator 6. Okt 2016 16:23

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
 
Ich glaube da hast du irgendwo noch einen Denkfehler in deinem Code. An der Klasse wird es so wie die aufgebaut ist und so wie du es sagst nicht liegen.

Ich vermute eher, dass da doch mit dem Init und so noch nicht so richtig funktioniert. Aber ohne mehr SourceCode oder eine ganze Unit wird das sehr schwer dir da weiterzuhelfen.

Genaugenommen haben MemoryLeaks ja auch nix mehr mit dem eigentlichen Thema zu tun. Die schnellere Erstellung der Nodes ist ja denke ich jetzt abgeschlossen.

Aber noch eine Sache zu deiner Freigabe:

Delphi-Quellcode:
for i := MeineObjectList.Count - 1 downto 0 do begin
  TMeinDatenSatz(MeineObjectList.Items[i]).Free;
  MeineObjectList.Delete(i);
end;
Brauchst du den Cast auf TMeinDatenSatz wirklich? Wie ist denn deine ObjectList deklariert? Benutzt du Generics oder noch nicht? Wenn du Generics benutzt, dann ist der Cast total überflüssig da du schon ein Objekt von genau dem Typ zurück erhältst.

EDIT: Mit "Massen" wird das nichts zu tun haben. Ich habe eine Anwendung in der mehrere 1000 (durchaus mal 20.000) Nodes und dementsprechend viele Objekte erzeugt werden. Bei der Freigabe bleibt rein gar nichts an Leaks zurück.

Jim Carrey 6. Okt 2016 16:33

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
 
Ich benutze die normale TObjectList. Generics versuche ich zu vermeiden wo es geht. Ohne ließt es sich einfacher finde ich.

Ich teste gleich mal, ob es an was anderem liegen könnte. Denn ich hab eben erst gesehen, dass ich in der Klasse auch eine Variable verwende die einen Enum-Typen hat.
Edit: ok das hat sich erledigt. Denn selbst wenn ich NUR die Klasseninstanz erzeuge und sie der ObjectList hinzufüge kommt der Leak. Das heißt ich weise keine Daten zu und er kommt dennoch.

Aviator 6. Okt 2016 16:59

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
 
Zitat:

Zitat von Jim Carrey (Beitrag 1350037)
Ich benutze die normale TObjectList. Generics versuche ich zu vermeiden wo es geht. Ohne ließt es sich einfacher finde ich.

Naja. Jeden das Seine. Aber gerade dieses rumgecaste macht es doch erst unübersichtlich. Das fällt ja bei den Generics weg. Lediglich beim Instanziieren und bei der Deklaration findet man ein solches Konstrukt
Delphi-Quellcode:
TObjectList<TMyDataType>
. Und dafür kann man sich dann noch einen eigenen Type anlegen und schon ist alles schön übersichtlich und man muss den Datentyp auch nur noch an einer Stelle im Code pflegen.
Delphi-Quellcode:
type TMyDataTypeList = TObjectList<TMyDataType>

Erzeug mal nur die Instanz und gib sie wieder frei und beende dann das Programm. Erscheint dann auch schon ein MemoryLeak?


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:49 Uhr.
Seite 5 von 6   « Erste     345 6      

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