AGB  ·  Datenschutz  ·  Impressum  







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

TVirtualTreeView gibt nicht alles frei

Ein Thema von hitzi · begonnen am 3. Dez 2004 · letzter Beitrag vom 10. Jul 2007
Antwort Antwort
Benutzerbild von hitzi
hitzi

Registriert seit: 2. Jan 2003
Ort: Eibau
768 Beiträge
 
Delphi 2010 Professional
 
#1

TVirtualTreeView gibt nicht alles frei

  Alt 3. Dez 2004, 13:52
Hallo,

ich nutze einen VirtualStringTree im Spaltenmodus.

Datenrecord:

Delphi-Quellcode:
type
  PTreeData = ^TTreeData;
  TTreeData = record
    FName : String;
    FPrivat : String;
    FMobile : String;
    FWork : String;
    FOther : String;
    FFax : String;
    FEmail : String;
    FHomepage : String;
    FOrganisation : String;
    FPosition : String;
    FStreet : String;
    FZIP : String;
    FCity : String;
    FState : String;
    FCountry : String;
    FNotes : String;
    fLuid : string;
  end;
Procedure zum Füllen mit Daten:
Delphi-Quellcode:
procedure TframeContacts.LoadContacts;
var Data: PTreeData;
    Node : PVirtualNode;
    i : integer;
begin
  vstContacts.BeginUpdate;
  try
    vstContacts.Clear;
    for i := 0 to PIM.RecordCount - 1 do
    begin
      Node := vstContacts.AddChild(nil);
      Data := vstContacts.GetNodeData(Node);
      Data^.FName := PIM.fvCard[i].FirstName + #32 + PIM.fvCard[i].Name;
      Data^.FPrivat := PIM.fvCard[i].TelHome;
      Data^.FMobile := PIM.fvCard[i].TelCell;
      Data^.FWork := PIM.fvCard[i].TelWork;
      Data^.FOther := PIM.fvCard[i].TelOther;
      Data^.FFax := PIM.fvCard[i].TelFax;
      Data^.FEmail := PIM.fvCard[i].Email;
      Data^.FHomepage := PIM.fvCard[i].URL;
      Data^.FOrganisation := PIM.fvCard[i].Organisation;
      Data^.FPosition := PIM.fvCard[i].Title;
      Data^.FStreet := PIM.fvCard[i].Street;
      Data^.FZIP := PIM.fvCard[i].ZIP;
      Data^.FCity := PIM.fvCard[i].City;
      Data^.FState := PIM.fvCard[i].State;
      Data^.FCountry := PIM.fvCard[i].Country;
      Data^.FNotes := PIM.fvCard[i].Note;
      Data^.fLuid := PIM.fvCard[i].Luid;
    end;
  finally
    vstContacts.EndUpdate;
  end;
end;
Procedure zum freigeben der Daten:

Delphi-Quellcode:
procedure TframeContacts.vstContactsFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var
  Data: PTreeData;
begin
  Data:=vstContacts.GetNodeData(Node);
  if Assigned(Data) then begin
    Data.FName := '';
    Data.FPrivat := '';
    Data.FMobile := '';
    Data.FWork := '';
    Data.FOther := '';
    Data.FFax := '';
    Data.FEmail := '';
    Data.FHomepage := '';
    Data.FOrganisation := '';
    Data.FPosition := '';
    Data.FStreet := '';
    Data.FZIP := '';
    Data.FCity := '';
    Data.FState := '';
    Data.FCountry := '';
    Data.FNotes := '';
    Data.fLuid := '';
  end;
end;
Ich lasse den Treeview mit Daten füllen und beim Destroy des Frames TframeContacts wird alles freigegeben auch. Theoretisch auch die Nodes. Leider nur theoretisch. Mit dem Taskmanager überwacht wird schnell erkenntlich, dass mit jedem Füllen/Freigeben rund 30KB nicht freigegeben werden.
Lasse ich das Erstellen der Nodes weg (TframeContacts.LoadContacts wird auskommentiert) wird jedes mal der Speicher beim Destroy des Frames auf dem Ursprungswert zurückgesetzt - sprich es wird alles was auf dem Frame war wieder freigegeben.
Fazit: Die Daten der Nodes werden nicht freigegeben. Wieso? Die Procedure TframeContacts.vstContactsFreeNode wird korrekt aufgerufen, wenn man das Programm im Einzelschritt durchgeht.

[EDIT]Ich weiß warum nicht alle Nodes freigegeben werden. Es sind 78 Zeilen im VirtualTreeView - die Procedure FreeNode wird aber nur insgesamt 19 mal aufgerufen. 59 Datensätze verbleiben also im Speicher.
Wieso ist das so?[/EDIT]

Gruss
Thomas
Besucht doch mal http://www.hitziger.net
  Mit Zitat antworten Zitat
Benutzerbild von hitzi
hitzi

Registriert seit: 2. Jan 2003
Ort: Eibau
768 Beiträge
 
Delphi 2010 Professional
 
#2

Re: TVirtualTreeView gibt nicht alles frei

  Alt 3. Dez 2004, 14:35
Um's mit den Worten des Entwicklers (Mike) zu erklären:

Zitat:
The key for VT to be so fast is to do things only if necessary. So, beside other things, it keeps a flag that tells it whether a node has been used or not. "Used" in this context means a nodes has been touch either because there was an iteration including that node or it has been displayed at least once. This flag indicates a socalled initialzed node and only initialized nodes are also passed to the application via OnFreeNode when they are about to be destroyed.

What you can do is to initialize a node explicitely (ValidateNode) or use the native way to VT (OnInitNode, OnInitChildren) and fill your data only when you initialize a node.
Ein vstContacts.ValidateNode(node, False); beim Datenfüllen erfüllt den Zweck.

Gruss
Thomas
Besucht doch mal http://www.hitziger.net
  Mit Zitat antworten Zitat
drchaos

Registriert seit: 15. Jun 2007
13 Beiträge
 
#3

Re: TVirtualTreeView gibt nicht alles frei

  Alt 10. Jul 2007, 17:45
Zitat:
Datenrecord:

Delphi-Quellcode:
type
  PTreeData = ^TTreeData;
  TTreeData = record
    FName : String;
    FPrivat : String;
    FMobile : String;
    FWork : String;
    FOther : String;
    FFax : String;
    FEmail : String;
    FHomepage : String;
    FOrganisation : String;
    FPosition : String;
    FStreet : String;
    FZIP : String;
    FCity : String;
    FState : String;
    FCountry : String;
    FNotes : String;
    fLuid : string;
  end;
Eine Frage: Wenn in diesem Datenrecord ausschließlich Felder mit konstanter Größe vorhanden wären, könnte ich doch auf die Freigabe der Knoten im Ereignis OnFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode) verzichten, nicht wahr?

Hintergrund: Bei 50000 und mehr Knoten dauert mir die Freigabe per "Fxyz := ''" oder "Finalize(NodeData^)" zu lange.

Kann ich also das Freigeben auslassen, wenn ich stattdessen die Strings mit fester Länge deklariere, z.B. FName : String[50] ?
(Es wäre auch keine großartige Speicherverschwendung, weil alle Zeichenketten eh ungefähr gleiche Länge haben werden)

edit:
ok, im VirtualTreeView-Doc steht:
Zitat:
TVirtualStringTree.OnFreeNode Event

Triggered when a node is about to be freed. This is the ideal place to free/disconnect your own data you associated with Node. Keep in mind, that data which is stored directly in the node does not need to be free by the application. This is part of the node record and will be freed when the node is freed. You should however finalize the data in such a case if it contains references to external memory objects (e.g. variants, strings, interfaces).
So etwas wie String[50] wird als Konstante ins Record geschrieben, ja? Oder erzeugt Delphi dann trotzdem Pointer, und reserviert Speicher außerhalb der Struktur?

nochmal edit:
Zitat:
Onlinehilfe Delphi5 zum Thema "Statische Arrays"
Ein Array der Form array[0..x] of Char wird als nullbasiertes Zeichen-Array bezeichnet, da sein Index bei 0 beginnt. Nullbasierte Zeichen-Arrays werden zum Speichern von nullterminierten Strings verwendet und sind kompatibel mit PChar-Werten. Informationen hierzu finden Sie unter Nullterminierte Strings.
Ok, Char-Arrays sind erwartungsgemäß statisch... ist denn nun String[50] äquivalent zu array[0..49] of Char?
  Mit Zitat antworten Zitat
Antwort Antwort


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 03:23 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