Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi prüfen, ob dyn. zur Runtime erzeugte Form Speicher freigibt? (https://www.delphipraxis.net/16943-pruefen-ob-dyn-zur-runtime-erzeugte-form-speicher-freigibt.html)

Hansa 25. Feb 2004 23:44


prüfen, ob dyn. zur Runtime erzeugte Form Speicher freigibt?
 
Eine Form wird zur Laufzeit erzeugt, mit

Delphi-Quellcode:
MyForm := TMyForm.Create (self);
Jetzt will ich wissen, ob der Speicher tatsächlich freigegeben wird, sofern ich die Form schließe. Ich bräuchte also für den Fall der Fälle (auch für anderes) den momentan freien Speicher.

Luckie 25. Feb 2004 23:59

Re: prüfen, ob dyn. zur Runtime erzeugte Form Speicher freig
 
Kuck dir mal GetHeapStatus an. Damit kannst du selber etwas bauen. Oder es gibt für Delphi auch so Experts mit denen man Memory-Leaks aufspüren kann. Mir fällt leider im Moment keiner ein.

Luckie 26. Feb 2004 00:30

Re: prüfen, ob dyn. zur Runtime erzeugte Form Speicher freig
 
Ich noch mal. Also kucken wir mal:
Delphi-Quellcode:
var
  NewFormModal, NewFormNotModal: TForm;

procedure TForm1.Button1Click(Sender: TObject);
begin
  NewFormModal := TForm2.Create(self);
  try
    NewFormModal.ShowModal;
  finally
    FreeAndNil(NewFormModal);
  end;
end;
Hier wird der Speicher von Form2 bestimmt wieder freigegeben.

Anders sieht es hier aus:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin
  NewFormNotModal := TForm2.Create(self);
  NewFormNotModal.Show;
end;
Jetzt ist die Frage, ob das Close in Form zwei die Form auch wieder aus dem Speicher schmeißt.

Testen wir das mal:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin
  if not Assigned(NewFormNotModal) then
  begin
    NewFormNotModal := TForm2.Create(self);
    NewFormNotModal.Show;
  end;
end;
Form2 wird hier nur erzeugt, wenn die Objektvariable nicht nil ist. Folglich kann man die neue Form auch nur einmal erzeugen. Jetzt der Test, schließt man Form2 mit Close, kann liefert Assigned immer noch true.

Daraus lassen sich jetzt zwei Schlüsse ziehen: Entweder wird der Speicher freigegeben und der Zeiger nicht auf Nil gesetzt. Was ich für unwahrscheinlich halte. Ich denke, die Borländer hätten dann auch den Zeiger genillt. Oder aber der Speicher wird nicht wieder freigegeben.

Selbst ein
Delphi-Quellcode:
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;
im OnClose der Form2 ändert nichts an obigen verhalten.

Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
begin
  Close;
  FreeAndNil(Unit1.NewFormNotModal);
end;
Endet mit einer AccessViolation.

So weit meine Untersuchungen. Leider bin ich zu keinem vernünftigem Ergebnisgekommen. :?

Robert_G 26. Feb 2004 00:39

Re: prüfen, ob dyn. zur Runtime erzeugte Form Speicher freig
 
Als Hansa seinen 2. (oder war's schon der 3. :gruebel: ) Thread zum Thema dyn. Forms aufgemacht hat, habe ich mir ein Form ertellt, lauter Komponenten draufgezogen (ListView, SynMemo, Memo, Edit,...) + 2 Buttons.
Der erste erzeuge 500 Instanzen von der Form, der 2. hat sie wieder entfernt.
Vorher waren es 7 MB Speichernutzung, mit 501 Forms etwa 50MB und nach dem Löschen etwa 9MB.
Ich habe zum entfernen der Forms "Close" verwendet und im OnClose stand "Action := caFree".

jbg 26. Feb 2004 00:43

Re: prüfen, ob dyn. zur Runtime erzeugte Form Speicher freig
 
Zitat:

Zitat von Luckie
Ich denke, die Borländer hätten dann auch den Zeiger genillt.

Und wie hätten die Borländer das anstellen sollen? Woher soll die Instanz denn wissen wieviele Referenzen denn auf sie zeigen?

Luckie 26. Feb 2004 00:45

Re: prüfen, ob dyn. zur Runtime erzeugte Form Speicher freig
 
Stimmt auch wieder. Und wie sieht es nun aus? Meine Testreihe ist ja damit hinfällig.

jbg 26. Feb 2004 00:50

Re: prüfen, ob dyn. zur Runtime erzeugte Form Speicher freig
 
Zitat:

Zitat von Robert_G
Vorher waren es 7 MB Speichernutzung, mit 501 Forms etwa 50MB und nach dem Löschen etwa 9MB.

Für den Unterschied gibt es zwei mögliche Erklärungen:
  • Es wurde Code ausgeführt, der Speicher reserviert, der erst wieder beim Beenden (also von TApplication.Destroy) freigegeben wird.
  • Der Delphi-Speichermanager hält freigegebenen Speicher zurück um ihn um Welten schneller an eine Speicherallozierung (GetMem/AllocMem/New/...) zu liefern, als es Windows je könnte. Somit bekommt Windows natürlich nichts von der Freigabe mit und zeigt im Taskmanager einen höheren Verbrauch an, auch wenn der Speicher für das Programm "frei" ist.
    Das ist auch der Grund für den enormen Speicherverlust beim zeichenweise Zusammenstückeln von Strings und dynamischen Arrays in Schleifen.

Luckie 26. Feb 2004 01:05

Re: prüfen, ob dyn. zur Runtime erzeugte Form Speicher freig
 
So. Habe es getestet. das:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin
  NewFormNotModal := TForm2.Create(self);
  NewFormNotModal.Show;
end;
hinterläßt ein Speicherleck. TForm.Close gibt also keinen Speicher frei.

Leuselator 26. Feb 2004 01:10

Re: prüfen, ob dyn. zur Runtime erzeugte Form Speicher freig
 
war mir so als ob es so sei, dass wenn man irgendwo "Create" schreibt, man immer auch "Free" bzw. "FreeAndNil" schreiben muß (sogenannte "Wer A sagt muß auch B sagen - Regel") ?

Luckie 26. Feb 2004 01:13

Re: prüfen, ob dyn. zur Runtime erzeugte Form Speicher freig
 
Nur wo willst du ein nicht modales Form freigeben? In der gleichen Prozedur geht nicht, dann wird es erst gar nicht angezeigt. Also wo?


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