![]() |
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. |
AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
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. 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. |
AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
Den Code habe ich leider nicht mehr.
Zitat:
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:
Nun gehe ich diese Liste durch und gebe alles frei:
Datensatz := TMeinDatenSatz.Create;
DatenSatz.MeinString := '123'; MeineObjektListe.Add(DatenSatz); // Liste hat OwnsObjects auf False, da das sonst Fehler gibt
Delphi-Quellcode:
Beim Beenden des Programms dann die Meldung, dass dutzende Unicode-Strings nicht freigegeben wurden. Das sind zu 100% die aus TMeinDatenSatz.
for i := MeineObjektListe.Count - 1 downto 0 do
begin TMeinDatenSatz(MeineObjektListe.Items[i]).Free; MeineObjektListe.Delete(i); end; MeineObjektListe.Free; |
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:
Wie sieht denn deine
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;
Delphi-Quellcode:
Klasse aus? Wird dort denn im Destructor immer alles schön freigegeben?
TMeinDatensatz
|
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. |
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.
|
AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
Zitat:
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:
Das hier ist eine 1-zu-1-Übertragung nur mit geänderten Variablen-Namen, um es einfacher zu halten.
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; 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. |
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:
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.
for i := MeineObjectList.Count - 1 downto 0 do begin
TMeinDatenSatz(MeineObjectList.Items[i]).Free; MeineObjectList.Delete(i); end; 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. |
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. |
AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!
Zitat:
Delphi-Quellcode:
. 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.
TObjectList<TMyDataType>
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. |
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