AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

VirtualStringTree: Speicherleck

Ein Thema von guidok · begonnen am 27. Okt 2009 · letzter Beitrag vom 2. Nov 2009
Antwort Antwort
Seite 1 von 3  1 23      
guidok

Registriert seit: 28. Jun 2007
417 Beiträge
 
#1

VirtualStringTree: Speicherleck

  Alt 27. Okt 2009, 14:01
Hallo zusammen!

Ich habe mir gerade mal meine werdende Anwendung mit FastMM angeschaut und auch prompt Speicherlecks gemeldet bekommen.

Ich konnte mittlerweile auch einen VST als "Täter" identifizieren. Ich füge da mehrere Knoten mit Unterknoten mit Hilfe von "AddChild" von folgender Struktur ein:

Delphi-Quellcode:
  PNodeData = ^TNodeData;
  TNodeData = record
    Id: Integer; //Identifikation des Feldes
    AuthReq: Integer; //Benötigte Authorisierung;
    Text: String; //Beschriftung
  end;
Im Ereignis OnFreeNode des VST mache ich folgendes:

Delphi-Quellcode:
procedure TSettingsForm.vstFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
  var
    NodeData: PNodeData;
begin
  NodeData := vst.GetNodeData(Node);
  if Assigned(NodeData) then begin
    //NodeData^.Text := '';
    Finalize(NodeData^.Text);
  end;
end;
Sooooo. Die Speicherlecks werden damit schon einmal weniger, aber es sind durchaus noch welche vorhanden. Sobald ich alle Knoten des Trees einmal aufgeklappt habe, sind sie dann alle weg.

Ist das ein Fehler vom VST oder mache ich noch etwas falsch?


Edit:

Ich habe mir gerade überlegt, ob es etwas mit den "Initialisieren" der Knoten zu tun hat und habe im Quelltext des VST folgendes gefunden:

Zitat:
// AddChild is a compatibility method and will implicitly validate the parent node. This is however
// against the virtual paradigm and hence I dissuade from its usage.
Wenn nicht mit "AddChild", wie soll ich das sonst machen?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#2

Re: VirtualStringTree: Speicherleck

  Alt 27. Okt 2009, 14:09
Wie erzeugst du PNodeDate?

genau andersrum mußt du es auch wieder freigeben!


z.B.:
Delphi-Quellcode:
NodeData := GetMem(SizeOf(TNodeData));
Initialize(NodeData);
...
Finalize(NodeData^);
FreeMem(NodeData);

// oder

New(NodeData);
...
Dispose(NodeData);
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
guidok

Registriert seit: 28. Jun 2007
417 Beiträge
 
#3

Re: VirtualStringTree: Speicherleck

  Alt 27. Okt 2009, 15:03
Zitat von himitsu:
Wie erzeugst du PNodeDate?
Gar nicht. Ich füge dem vst nur einen neuen Knoten hinzu.

Delphi-Quellcode:
Node := vst.AddChild(ParentNode);
Data := vst.GetNodeData(Node);
Das Problem ist eher, dass nur die Knoten im vst.OnFreeNode freigegeben werden, die auch einmal aufgeklappt waren.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: VirtualStringTree: Speicherleck

  Alt 27. Okt 2009, 15:23
Zitat von guidok:
Das Problem ist eher, dass nur die Knoten im vst.OnFreeNode freigegeben werden, die auch einmal aufgeklappt waren.
Den Satz habe ich schonmal hier im Forum gelesen

Nichtsdestotrotz sollte man eh nie Datenhaltung und GUI vermischen.
Ich habe meine Klassenstruktur in denen die Daten stehen und die auch separat freigegeben wird. Dem VST gebe ich nur den entsprechenden Zeiger zu je einem Element dieser Datenstruktur.

Edit: Und dort wo ich den Satz schonmal gelesen habe, stand auch die Lösung:
Es ist vom Entwickler direkt so vorgesehen, was du beschreibst.
--> It's not a bug, it's a feature
Entweder du gehst so vor, wie ich, oder du machst es wie im Link beschrieben: Mit ValidateNode jeden Knoten anfassen, dadurch wird auch onFreeNode aufgerufen, wenn es soweit ist (--> Performanceeinbußen), oder ist bei onInitNode den Speicher belegen.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#5

Re: VirtualStringTree: Speicherleck

  Alt 27. Okt 2009, 15:29
Ach nee, stimmt ja, der Record wird ja direkt an die Node-Struktur angehängt

nja, zumindestens Freigeben würde ich es so, falls du mal den Record erweiterst und z.B. noch 'nen String einfügst.
Finalize(NodeData^); Diese NodeDataSize (oder wie das nochmal hieß) hast du auch richtig gesetzt?


Hast du eventuell sowas wie FreeOnCollapse aktiviert?


[add]
ich mach es meißtens auch nur so wie sirius,
aber das liegt daran, daß ich diese Structuren eh extern hab und immer nur eine Teilmenge im Tree anzeige und davon auch nur der grade sichtbare (aufgeklappte) Teil im Tree vorhanden ist.

läßt sich auch schneller der Tree füllen, wenn da da insgesamt viel reinmacht, nur den sichtbaren Teil einfügt und den Rest, wenn nötig Stück für Stück nachläd.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
guidok

Registriert seit: 28. Jun 2007
417 Beiträge
 
#6

Re: VirtualStringTree: Speicherleck

  Alt 28. Okt 2009, 07:18
Zitat:
Den Satz habe ich schonmal hier im Forum gelesen
Wusst ich doch, dass ich das auch schon mal gelesen hatte. Hab es nur nicht gefunden. Danke.

Zitat:
Nichtsdestotrotz sollte man eh nie Datenhaltung und GUI vermischen.
Ich habe meine Klassenstruktur in denen die Daten stehen und die auch separat freigegeben wird. Dem VST gebe ich nur den entsprechenden Zeiger zu je einem Element dieser Datenstruktur.
Darum bemühe ich mich auch, bin aber anscheinend noch nicht ganz so weit. Vielleicht könnt ihr mir ja einen Denkanstoß geben?

In diesem Fall nutze ich den Tree zur Anzeige von Einstellungen, also z.B.

|-Verzeichnisse
| |
| |------Archivdaten C:\Foo
| |------Temporäre Daten C:\Bar
|
|-Benutzerhinweise
|
|------Neue Daten vorhanden +
|------Irgendwas anderes -

Die eigentlichen Daten (also das was rechts in der zweiten Spalte steht) sind natürlich in einer anderen Datenstruktur vorhanden, allerdings kann ich da ja schlecht die Baumstrukturinformationen und die "Beschriftung" der Felder mit vorhalten, oder?

Ich habe auf das Beispiel oben bezogen sowas:

path_archiv = C:\Foo
path_temp = C:\Bar
info_new = 1
info_somthingelse = 0

Wie macht ihr das? Wie würdet ihr das machen?
  Mit Zitat antworten Zitat
hoika
Online

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#7

Re: VirtualStringTree: Speicherleck

  Alt 28. Okt 2009, 08:36
Hallo,

Zitat:
Die eigentlichen Daten (also das was rechts in der zweiten Spalte steht) sind natürlich in einer anderen Datenstruktur vorhanden
Wie vorhanden ?
Als Klasse ?

Dann packe einen "Pointer" der Klasse in die NodeData mit rein.

Delphi-Quellcode:
type
  TInfo = class
    Text: String;
  end;


  TNodeData = class
    Id: Integer; //Identifikation des Feldes
    AuthReq: Integer; //Benötigte Authorisierung;
    Info: TInfo;
  end;
Es ist übrigens keine svchechte Idee, statt dem Record
auch gleich eine Klasse als NodeData zu benutzen.
Vielleicht kannst du ja gleich alle benötigten Daten (Id, AuthReq)
in diese Info-Klasse packen.



Heiko
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#8

Re: VirtualStringTree: Speicherleck

  Alt 28. Okt 2009, 08:54
Delphi-Quellcode:
TNodeData = record
  Id: Integer; //Identifikation des Feldes
  AuthReq: Integer; //Benötigte Authorisierung;
  Text: String; //Beschriftung
end;
Wenn man das so sieht, dann hast du es ja schon getrennt
ID ist dann wohl dein externer Datensatz
und das Andere betrifft nur die GUI/Anzeige

Du könntest natürlich auch nur die ID in .Data speichern
und dir dann noch Funktionen anlegen, welche dir Anhand der ID die Authorisierung oder die Beschriftung liefern, aber so ist es anscheinend doch auch schon recht gut getrennt,
es sei denn du nutzt schon zum Befüllen deines Records solche Funktionen, dann kannst du es natürlich auch später immernoch machen und brauchst nur die ID
function TFormX.GetTVCaption(ID: Integer): String;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
guidok

Registriert seit: 28. Jun 2007
417 Beiträge
 
#9

Re: VirtualStringTree: Speicherleck

  Alt 28. Okt 2009, 09:20
Zitat von himitsu:
Delphi-Quellcode:
TNodeData = record
  Id: Integer; //Identifikation des Feldes
  AuthReq: Integer; //Benötigte Authorisierung;
  Text: String; //Beschriftung
end;
Wenn man das so sieht, dann hast du es ja schon getrennt
ID ist dann wohl dein externer Datensatz
und das Andere betrifft nur die GUI/Anzeige
Stimmt genau! ID ist die Identifikation des Feldes in der "Datenhaltung".

Ein einzelner Datensatz ist bei mir ein CollectionItem und diese werden in einer Collection gehalten, insofern könnte ich für den Knoten auch einen Zeiger auf das CollectionItem angeben.

Ich sehe derzeit folgende Möglichkeiten:

1. Ich lasse es so wie es ist und validiere die Knoten beim Einfügen, um auch alle wieder entfernt zu bekommen.

2. Ich lasse ID weg und füge stattdessen gleich einen Zeiger auf das CollectionItem in den Knoten ein, was vermutlich keine schlechte Idee ist, weil ich dann direkt auf die Daten zugreifen kann ohne vorher nach der ID suchen zu müssen.

3. Ich füge nur einen Zeiger auf ein CollectionItem ein und halte alle Daten (also auch die, die ich nur für die "hübschere" Anzeige benötige) in der Collection. Das führt natürlich dazu, das ich ein paar mehr Daten sichern muss (Inifile, XML-Datei oder DB), die eigentlich nur für die GUI interessant sind. Vorteil wäre hier, dass ich ziemlich flexibel neue Werte einfügen könnte, weil das alles dynamisch aus dem Datenbestand aufgebaut wird.

4. Ich füge nur die ID ein und hole mir die Werte wie von himitsu vorgeschlagen über entsprechende Funktionen.

Darüber werde ich einmal nachdenken müssen. Vielen Dank für die Inspiration!
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: VirtualStringTree: Speicherleck

  Alt 28. Okt 2009, 10:38
Wieso baust du deine Collection nicht so auf, wie die Baumstruktur auch aussieht?
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:05 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz