Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Speicherverwaltung und .Free (https://www.delphipraxis.net/24150-speicherverwaltung-und-free.html)

skyphab 16. Jun 2004 10:38


Speicherverwaltung und .Free
 
Hallo zusammen,

da ich zur Zeit mit Objekten und Objektlisten hantiere für ein Programm, dass 24h am Tag 7 Tage die Woche laufen muss (quasi immer ;)), ist es natürlich wichtig, dass der Speicher nicht irgendwann volläuft, weil ich instanzierte Objekte nicht richtig freigebe.

Daher meine Frage was ich beachten muss.
In einem Fall habe ich vier Klassen, die jeweils eine ObjectList haben und in dieser ObjectList 1..n instanzierte Objekte 'ablegen' (Abgelegt werden nur Zeiger auf die Objekte, oder wie ist das?).

Im Verlauf des Programms gibt es ein wildes Erstellen, Löschen, Hinzufügen, Neuerstellen von diesen Objekten und deren Listen, also muss das sauber laufen.
Die ObjectList erstelle ich mit dem Parameter true (OwnsObjects). Wie ist jetzt der saubere Weg, das Objekt und alle zugehörenden Objekte freizugeben?
Wenn ein Objekt der obersten Klasse gelöscht wird und ich es im destructor über Self.Free freigebe, sollte die Objektliste im gleichen Zuge freigesetzt werden, oder bedarf es dazu erst einem Objektliste.Free?
Die ganze Freisetzung muss sich dann durch alle Objekte ziehen, klappt das so oder muss ich noch etwas beachten?

Woran erkenne ich, ob das funktioniert?
Danke schonmal :)

Muetze1 16. Jun 2004 10:42

Re: Speicherverwaltung und .Free
 
Moin!

1. Im Destructor ein Self.Free?? Sehr interessant und sollte nicht funktionieren.
2. Wenn eine TObjectList OwnsObject auf True hat, dann wird beim entfernen eines Objektes diesea auch automatisch freigegeben.
3. Bsp: Wenn du bei der ObjectList ein Clear aufrufst, dann werden alle enthaltenen Objekte freigegeben und aus der Liste entfernt

MfG
Muetze1

jbg 16. Jun 2004 11:14

Re: Speicherverwaltung und .Free
 
Zitat:

Zitat von Muetze1
1. Im Destructor ein Self.Free?? Sehr interessant und sollte nicht funktionieren.

Funktionieren tut das schon. Man schafft nur eine Endlosrekursion.

Zitat:

2. Wenn eine TObjectList OwnsObject auf True hat, dann wird beim entfernen eines Objektes diesea auch automatisch freigegeben.
OwnsObjects ist per Standardeinstellung auf True gesetzt. Wenn man ein Objekte aus der ObjectList entfernen will, ohne das es freigegeben wird, muss man die Extract Methode von TObjectList nutzen.

nieurig 16. Jun 2004 12:41

Re: Speicherverwaltung und .Free
 
Zitat:

Woran erkenne ich, ob das funktioniert?
Ich habe mal bei einem ähnlichen Problem die Funktion getHeapStatus() mit TotalAllocated eingesetzt. Problem dabei war, dass auch der genutzte Speicher durch die Oberfläche angezeigt wird und dieser in Abhängigkeit von den User-Aktivitäten stark schwankt. Trotzdem konnte man recht gut verfolgen, ob "Speicher verbraucht" wird.

Niels

skyphab 17. Jun 2004 08:47

Re: Speicherverwaltung und .Free
 
Das mit dem GetHeapStatus ist super, danke!

Damit habe ich jetzt herausgefunden, dass das Freigeben der obersten Objektliste funktioniert.
Wenn in der Objektliste aber ein Objekt angelegt wird, dass wiederum eine Objektliste erzeugt, wird beim clear der 'obersten' Objektliste aber der Speicher der untersten Objektliste nicht freigegeben.

Zur Verdeutlichung (Ich habe den unwichtigen Teil des Codes rausgeschnippelt):

Klasse TAuftraege
Code:
procedure TAuftraege.Auftrag_Hinzufuegen(I_Auftrag: RAuftrag);
begin
  Objektliste.Add(TAuftrag.Create(I_Auftrag));
end;
Klasse TAuftrag
Code:
constructor TAuftrag.Create(I_Auftrag: RAuftrag);
begin
  Auftrag := I_Auftrag;
end;
Bei (In TAuftraege):

Code:
Objektliste.Clear;
und anschließendem neu Anlegen der Objekte, ändert sich der laut GetHeapStatus der zugewiesene Speicher nicht.

Allerdings so (Änderung bei TAuftrag.Create):

Klasse TAuftraege
Code:
procedure TAuftraege.Auftrag_Hinzufuegen(I_Auftrag: RAuftrag);
begin
  Objektliste.Add(TAuftrag.Create(I_Auftrag));
end;
Klasse TAuftrag
Code:
constructor TAuftrag.Create(I_Auftrag: RAuftrag);
begin
  RollenListe := TObjectList.Create(true);
  Auftrag := I_Auftrag;
end;
wird beim Objektliste.Clear und anschließendem Neuanlegen immer mehr Speicher belegt (~100Byte). Also wird wohl die Objektliste 'Rollenliste' nicht korrekt freigegeben. Ich muss nicht mal ein Objekt in diese Liste stellen.

Muss ich in diesem Fall Rollenliste irgendwo freisetzen? Ich habe in destructor TAuftrag.free Rollenliste.Free reingemacht, aber gebracht hat es nichts? :cry:

skyphab 17. Jun 2004 16:35

Re: Speicherverwaltung und .Free
 
Hab's gefunden :-D

Code:
destructor TAuftrag.Destroy;
begin
  RollenListe.Free;
  inherited Destroy;
end;
:wall:

Aber der Tipp mit dem GetHeapStatus war wirklich Gold wert! Dickes Danke! :thuimb:

skyphab 20. Jul 2004 12:43

Re: Speicherverwaltung und .Free
 
Hallo!

Ich krame den Thread nochmal aus, vielleicht kann mir jemand einen Tipp geben:

Ich bin gerade schier am verzweifeln. Ich lese Dateien momentan alle 1500ms mit einem Timer ein. Dabei werden die Inhalte dieser Dateien als Create-Parameter für erzeugende Objekte benutzt, die in einer ObjectList stehen.
Jedesmal bevor ich neue Objekte in diese Objectlist stelle, mache ich Objectlist.clear.

Es funkioniert alles, nur ich habe das Gefühl, dass ich Speicherleaks habe. Mit GetHeapStatus.TotalAllocated schwankt der zugewiesene Speicher die ganze Zeit. 224888 für mehrere Sekunden, dann 224600, später wieder 224910. Woher kommen diese Schwankungen? So wie es aussieht geht der Speicherverbrauch zurück, um dann später wieder mehr zu werden. Dann geht's wieder zurück und später noch mehr, so als würde sich das Ganze aufschaukeln. :(

Wenn ich mit Objektliste und Objekten arbeite, was muss ich denn noch zuästzlich beachten?!

Objektliste.add(Create(Objekt));
und später
Objektliste.clear;

Mit dem Clear werden doch alle Instanzen, die in dieser Objektliste waren, freigesetzt und der Speicher freigegeben? Oder nicht? Es ist zum heulen :cry:

maximov 20. Jul 2004 13:22

Re: Speicherverwaltung und .Free
 
Zitat:

Zitat von skyphab
Hallo!
...
Objektliste.add({ Was hat das zu bedeuten? ->}Create(Objekt));
und später
Objektliste.clear;

.. :cry:

? Welches create wird denn da aufgerufen und warum ohne klasse ?

teebee 20. Jul 2004 14:16

Re: Speicherverwaltung und .Free
 
Zitat:

Zitat von skyphab
Mit dem Clear werden doch alle Instanzen, die in dieser Objektliste waren, freigesetzt und der Speicher freigegeben? Oder nicht? Es ist zum heulen :cry:

Ja, wenn OwnsObject der ObjectList auf True steht, was standardmäßig der Fall ist, und das jeweilige Objekt sich selber sauber freigeben kann, also der Destruktor ordentlich programmiert ist.

Übrigens ist MemProof ein gutes Tool, um seine Programme auf Speicherlecks zu prüfen.

Gruß, teebee

skyphab 20. Jul 2004 15:09

Re: Speicherverwaltung und .Free
 
Zitat:

Zitat von teebee
Zitat:

Zitat von skyphab
Mit dem Clear werden doch alle Instanzen, die in dieser Objektliste waren, freigesetzt und der Speicher freigegeben? Oder nicht? Es ist zum heulen :cry:

Ja, wenn OwnsObject der ObjectList auf True steht, was standardmäßig der Fall ist, und das jeweilige Objekt sich selber sauber freigeben kann, also der Destruktor ordentlich programmiert ist.

Übrigens ist MemProof ein gutes Tool, um seine Programme auf Speicherlecks zu prüfen.

Gruß, teebee

MemProof werde ich mal testen, danke!

Das mit den Destruktoren ist mir noch ein kleines Rätsel. Was muss ich denn behandeln, im Destructor? Muss ich irgendwelche Variablen zurücksetzen, etc.? Oder nur mit diesem Objekt erzeugte Objekte freigeben?

Edit: Also wenn ich das Ganze mit MemProof laufen lasse, erhöht sich die Anzahl der Pointer und die Größe, um dann kurz danach, nach Freigeben der Objekte wieder auf den Urpsrungswert zurückzufallen (Wenn die eingelesenen Dateien sich nicht ändern)

Wenn ich im Programm in einem Destructor eine Objektliste nicht freigebe, erhöht sich die Anzahl der Pointer immer mehr.

Also habe ich keine Speicherleaks? :-D Würde mich freuen, weil das Verwenden von Sharemem scheint mir nicht 100% treffend genug zu sein (die besagten Schwankungen). Vielen Dank für den Link zum Programm! :spin2:

Edit: Ich habe einen Haufen Meldungen bei 'Resurces Details':
"GetMem allocates memory from the RTL memory manager and returns a pointer. The returned pointer must be freed with FreeMem"

Ich arbeite unter anderem mit einem dynamischen Array. Hat das was damit zu tun? :gruebel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:49 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