Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Packed record mit Dictionary als Variable, Richtig aufräumen (https://www.delphipraxis.net/214464-packed-record-mit-dictionary-als-variable-richtig-aufraeumen.html)

SusiT 15. Jan 2024 21:52

Packed record mit Dictionary als Variable, Richtig aufräumen
 
Guten Abend,

ich habe einen packed Record mit einem Dictionary als Variable angelegt.

Delphi-Quellcode:
TCurrActivity = packed record
 ActId                : Integer;
 NsRelatedRowsIds     : TDictionary<String,Integer>;
 procedure init;
 procedure clear;
end;

Beim Erstellen wird init und beim aufräumen wird clear aufgerufen.

Delphi-Quellcode:
procedure TCurrActivity.init;
begin
   ActId := 0;
   Self.NsRelatedRowsIds := TDictionary<String,Integer>.Create;
end;

procedure TCurrActivity.clear;
begin
 self := default(TCurrActivity);
end;
Mir erschließt sich gerade nicht wie die richtige Herangehensweise ist um das Dictionary richtig aufzuräumen, sobald das Packed Record freigegeben wird.

Normalerweise mache ich

Delphi-Quellcode:
NsRelatedRowsIds.Clear;
FreeAndNil(NsRelatedRowsIds);
um nach getaner Arbeit den Speicher eines Dicts wieder freizugeben.

Wie verhält sich das, wenn ich das Dict in einem packed record verschachtelt ist?

Am liebsten würde ich folgendes machen:

Delphi-Quellcode:
procedure TCurrActivity.clear;
begin
// Self.NsRelatedRowsIds.Clear;
// FreeAndNil(Self.NsRelatedRowsIds);

 self := default(TCurrActivity);

 Self.NsRelatedRowsIds.Clear;
 FreeAndNil(Self.NsRelatedRowsIds);
end;
um das Dict im packed record richtig aufzuräumen, allerdings
gibt dies Zugriffsverletzungen.

Daher die Frage muss ich ein Dict welches in einem packed record Created ist auch wieder freigeben oder ist dies egal?
Macht das ganze Konstrukt bzw. die Idee überhaupt Sinn bzw ist so umsetzbar?


Vielen Dank und viele Grüße

himitsu 16. Jan 2024 02:49

AW: Packed record mit Dictionary als Variable, Richtig aufräumen
 
Delphi-Quellcode:
:= Default(...)
überschreibt einfach alles mit Nullen.
Von den Zeiger-Typen werden ausschließlich Managed-Typen automatisch freigegeben. (Variant, LongStrings, Interfaces und dynamische Arrays)
Also erst das Objekt freigeben und danach den Record leeren.

mögliche Lösungen
* Object anstatt Record
* Interface statt Object
* dynamisches Array anstatt Liste/Dictionary (mit dem generischen TArray.BinarySearch kann man es wie eine sortierte Liste behandeln -> Suchen, sowie für's Insert)
* Bei Google suchenCustom Managed Records
* ...

https://blogs.embarcadero.com/custom...o-delphi-10-4/
https://docwiki.embarcadero.com/RADS...anaged_Records

Der schöne Günther 16. Jan 2024 08:42

AW: Packed record mit Dictionary als Variable, Richtig aufräumen
 
Wie schon gesagt, du musst das Dictionary explizit freigeben, sonst verbleibt es auf ewig im Speicher. Oder du stellst es auf einen Interface-Typ um, dann brauchst du dich darum nicht mehr kümmern.

Ob der record packed ist oder nicht ist hier eigentlich völlig egal.

SusiT 16. Jan 2024 08:43

AW: Packed record mit Dictionary als Variable, Richtig aufräumen
 
Habe ich verstanden, vielen Dank.

Ich nutze die packed records sehr gerne, da diese sich recht leicht erstellen und verwalten lassen.

Grundsätzlich ist es aber möglich, dass komplexere Speicherstrukturen in einem packed record enthalten sind nehme ich an? (Wie zb. Dictionarys)

Ohne das irgendwelche komischen Sachen passieren :-D


Viele Grüße

Der schöne Günther 16. Jan 2024 09:13

AW: Packed record mit Dictionary als Variable, Richtig aufräumen
 
Ein TDictionary ist an sich nicht komplex, das ist ja nur ein "Zeiger" auf einen Bereich anderswo, außerhalb des Records. Eben deshalb musst du das Dictionary explizit wieder freigeben.

Es gibt noch Typen bei denen der Compiler (bzw. die automatische Referenzzählung "ARC") sich darum kümmert, den Speicher wieder freizugeben. Das ist beispielsweise der Fall bei Strings, oder dynamischen Arrays. Da musst du dich auch nicht drum kümmern. Würdest du ein für dich passendes Interface um dein TDictionary basteln und dann ein IDictionary verwenden, müsstest du dich um die Freigabe auch nicht mehr kümmern 😊


Meine Frage wäre noch, weshalb das
Delphi-Quellcode:
packed
? Bist du dir sicher, dass du das brauchst? Ich kenne das eigentlich nur, wenn du eine Struktur 1:1 serialisieren willst (z.B. für Netzwerk-Übertragung oder Speichern in eine Datei), aber das kann man sich eh schenken wenn du zeigerbasierte Typen (wie z.B. ein Dictionary) drin hast.

Delphi-Quellcode:
packed
macht den Speicherzugriff auf Teile des Records nur langsamer, weil verhindert wird, dass (für dich unsichtbare) Lücken zwischen den Feldern des Records gepackt werden, damit der Computer für ihn besser den Speicher da rauslesen kann.

himitsu 16. Jan 2024 09:43

AW: Packed record mit Dictionary als Variable, Richtig aufräumen
 
Zitat:

Zitat von SusiT (Beitrag 1531978)
Ich nutze die packed records sehr gerne, da diese sich recht leicht erstellen und verwalten lassen.

Das hat aber nichts mit Packed zu tun.

So lange es nicht auf jedes einzelne Byte drauf an kommt oder der Record für Speicherung oder Datenübertragung (in andere Systeme/Programme/...) verwendet wird, kann es aber nachteile bringen, wenn Speicher ungünstig ausgerichtet ist.

Andreas13 16. Jan 2024 09:53

AW: Packed record mit Dictionary als Variable, Richtig aufräumen
 
Zitat:

Zitat von himitsu (Beitrag 1531962)
... Also erst das Objekt freigeben und danach den Record leeren....

Das verstehe ich nicht ganz... :oops: Sollte die Reihenfolge nicht anders sein?

TBx 16. Jan 2024 10:17

AW: Packed record mit Dictionary als Variable, Richtig aufräumen
 
Zitat:

Zitat von Andreas13 (Beitrag 1531988)
Zitat:

Zitat von himitsu (Beitrag 1531962)
... Also erst das Objekt freigeben und danach den Record leeren....

Das verstehe ich nicht ganz... :oops: Sollte die Reihenfolge nicht anders sein?

Nein, das Leben des Records wird durch Überschreiben mit Nullwerten realisiert. Damit würde mann auch den Zeiger überschreiben, der zum Löschen des Objektes benötigt wird.

Andreas13 16. Jan 2024 10:24

AW: Packed record mit Dictionary als Variable, Richtig aufräumen
 
Danke, jetzt habe ich das verstanden!:thumb:

jaenicke 16. Jan 2024 12:52

AW: Packed record mit Dictionary als Variable, Richtig aufräumen
 
Zitat:

Zitat von SusiT (Beitrag 1531957)
Daher die Frage muss ich ein Dict welches in einem packed record Created ist auch wieder freigeben oder ist dies egal?
Macht das ganze Konstrukt bzw. die Idee überhaupt Sinn bzw ist so umsetzbar?

Technisch bekommt man das zwar hin, aber ich halte es für keine saubere Lösung, wenn man manuell verwaltete Elemente wie Klassen in automatisch verwaltete Records packt. Umgekehrt ist das kein Problem, aber in der Richtung muss man immer aufpassen, dass man keinen Fehler macht.

Ein Problem ist z.B., dass ein Record beim Zugriff ggf. komplett kopiert wird, z.B. beim Abrufen aus einer Liste. Und schon hat man den Record zweimal im Speicher mit der gleichen einmal erzeugten Liste. Bei einer Klasse hast du dann nur zwei Referenzen auf den gleichen Speicher.

Insgesamt machst du dir das Leben an der Stelle deutlich einfacher, wenn du Klassen verwendest. Dort erzeugst du die Liste im Konstruktor und gibst sie im Destruktor frei. Dass das mit Records mittlerweile auch geht (Custom Managed Records), ist schon richtig, aber das ist dann nicht einfacher als mit Klassen, sondern an einigen Stellen ein großer Nachteil, und außerdem macht man leichter Fehler dabei.

Der einzige echte Vorteil von Records ist, dass bei massenhafter Verwendung (viele zehntausend z.B.) die Performance und die Speicherbelastung besser sind. Das macht sich aber wirklich erst bei sehr sehr vielen Records bemerkbar. Abgesehen von solchen Optimierungsproblemen überwiegen die Nachteile von Records gegenüber Klassen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:48 Uhr.
Seite 1 von 2  1 2      

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