![]() |
Memoryleak bei dynamischen Forms ?
Ich hab hier ein kleines Testprogramm geschrieben, das, neben dem Hauptformular, mehrere Unterformulare hat (mit je einem Riesenbild zur Verdeutlichung ).
Diese Unterformulare werden im Hauptform per Listbox ausgewählt und per Buttonclick dynamisch erzeugt:
Delphi-Quellcode:
Soweit funktioniert das ganze auch wunderbar.
procedure THauptformular.Showform(Item:integer);
begin case item of 0 : begin form1 := TForm1.Create(self); form1.onclose := DoCloseSubForm; form1.Tag := item; form1.Show; end; 1 : begin form2 := TForm2.Create(self); form2.OnClose := DoCloseSubForm; form2.Tag := item; form2.Show; end; 2 : begin form3 := TForm3.Create(self); form3.onclose := DoCloseSubForm; form3.Tag := item; form3.Show; end; 3 : begin form4 := TForm4.Create(self); form4.onclose := DoCloseSubForm; form4.Tag := item; form4.Show; end; 4 : begin form5 := TForm5.Create(self); form5.onclose := DoCloseSubForm; form5.Tag := item; form5.Show; end; 5 : begin form6 := TForm6.Create(self); form6.onclose := DoCloseSubForm; form6.Tag := item; form6.Show; end; 6 : begin form7 := TForm7.Create(self); form7.onclose := DoCloseSubForm; form7.Tag := item; form7.Show; end; end; end; Beim Schließen des Unterformulars wird die Instanz nun wieder freigegeben:
Delphi-Quellcode:
Das scheint aber nur teilweise zu funktionieren. Lt. Taskmanager bleiben etwa 650Kb stehen und zwar jedesmal, also wenn ich die Unterformulare 5 mal aufrufe, bleiben insgesamt 3250 Kb stehen !!. Wie kommt das und wie kann man das verhindern ?
procedure THauptformular.DoCloseSubForm(Sender: TObject;
var Action: TCloseaction); begin action := caFree; end; |
Re: Memoryleak bei dynamischen Forms ?
Werden die Formulare auch wirklich zerstört und nicht nur versteckt? Ich hatte mit der Freigabe an der Stelle bis jetzt kein Problem.
Gib auch mal explizit dein "Riesenbild" mit frei. Gruß oki |
Re: Memoryleak bei dynamischen Forms ?
Wie schließst du die Fenster?
|
Re: Memoryleak bei dynamischen Forms ?
Nimm doch einfach MemProof oder FastMM, damit hast Du gleich die Zeile, in der das Leck auftritt.
|
Re: Memoryleak bei dynamischen Forms ?
@mkinzler
Über caFree im onClose-Event (siehe Quelltext). @alzaimar Memproof hab ich probiert, aber der zeigt nada an. FastMM werd ich noch probieren. |
Re: Memoryleak bei dynamischen Forms ?
Zitat:
|
Re: Memoryleak bei dynamischen Forms ?
Nein..wie man aus dem Quelltext sehen kann, weise ich jedem Unterformular die DoCloseSubForm-Methode des Hauptformulars zu (die hat nix mit onClose vom Hauptformular zu tun !!). In dieser wird das Formular freigegeben via caFree.
Das Hauptformular wird ganz normal beim Programmstart erzeugt und am ende freigegeben. |
Re: Memoryleak bei dynamischen Forms ?
Hupsa... Au weia :oops:
Ah.. ich weiss es (vielleicht). Wieso sollten diese Formulare freigegeben werden, außer Du schließt sie alle explizit am Programmende? Ersetze das 'Formx := TFormx.Create(Self)' durch ein 'Application.CreateForm (TFormx, Formx)' und dann werden die Formulare auch beim Programmende freigegeben. |
Re: Memoryleak bei dynamischen Forms ?
Ähm...ok...vielleicht auch mal mein vorgehen :):
Ich starte das Programm -> Hauptformular wird normal aufgebaut -> auswahl eines der Unterformulare ->Speicheranstieg ->Unterformular wird angezeigt -> Ich schließe das Unterformular -> wird teilweise freigegeben, es bleiben aber ca. 650 K stehen -> Ich öffne ein anderes Unterformular -> Speicheranstieg -> Unterformular wird angzeigt. -> Ich schließe auch dieses -> wieder nur teilweise freigegeben, wieder bleiben ca 650K stehen. Wenn ich das Programm komplett beende bleibt in dem sinn nix stehen (lt. Memproof und FastMM). Was interresant ist, wenn ich das gleiche Unterformular zweimal auf und zu mache bleibts bei den 650K. |
Re: Memoryleak bei dynamischen Forms ?
Hallo,
das caFree spielt AFAIK nur eine Rolle bei MDI, weil dort der Standard caHide ist. ein Formular muss explizit per Form.Free freigegeben werden, es sei denn du nimmst das oben erwähnte Application.CreateForm. Ein Modales Fenster muss also z.B. immer so aufgerufen werden
Delphi-Quellcode:
Form:= TForm.Create(Self);
try Form.ShowModal; finally Form.Free; end; Zum Taskmanager, wann genau stehen die 3MB zu viel Speicher drin ? So richtig verstehe ich dein "5mal aufrufen" nicht. setz doch mal nen Breakpoint auf TForm1.Destroy (Ereugnis erzeugen, irgendwas dort machen, z.B. i:= 0) und schaue nach, ob der Breakpoint angesprungen wird. Das mit dem "bleibt" 650 kB kann ich jetzt nicht so verstehen ;) Heiko |
Re: Memoryleak bei dynamischen Forms ?
Ach Gott, der Windows-Taskmanager... Der zeigt das sowieso nicht richtig an (meine Erfahrung). Hab mich mal totgesucht an einem Speicherleck, ähnlich wie deins. Da war aber nix. Trotzdem hatte mein Programm angeblich 5MB, die es nicht freigegeben hat...
Das FastMM nichts angemeckert hat, war da auch nichts. |
Re: Memoryleak bei dynamischen Forms ?
caFree hat erstmal nix mit MDI zu tun, sonst würden meine Formulare garnicht freigegeben werden (ein Unterformular belegt lt. TM ca. 5 MB-Speicher wenn es erzeugt und angezeigt ist !!).
Also..ich hab insgesamt 8 Formulare: Hauptformular (THauptformular) -> erzeugt wird das über Application.CreateForm. Auf diesem befindet sich eine Listbox zur Auswahl des anzuzeigenden Formulars, sowie ein Button, der das Formular erzeugt und anzeigt (ruft mit itemindex der Listbox die Methode ShowForm auf). Form1 - Form7 (mit entsprechender Klasse TForm1-TForm7). Die werden dynamisch via ShowForm-Methode des Hauptformulars erzeugt und angezeigt. Um diese Formulare automatisch zu schließen, wird nach der Erzeugung die Methode DoCloseSubForm im onClose-Event als handler hinterlegt, was bewirkt (zumindest sollte es das), das das Formular beim Schließen (via X-Button) gleich freigegeben wird. Nach dem Programmstart gehe ich wie folgt vor: ->wähle form2 in der Listbox aus und drücke den Button (form2 wird erzeugt und angezeigt) ->Speicherbedarf steigt um 5 MB an ->schließe form2 via x-button ->Speicherbedarf sinkt um 4250 Kb (650Kb zu wenig, sollte ja eigentlich 5 MB sein !) ->wähle form 6 in der Listobx aus und drücke den Button (form6 wird erzeugt und angezeigt) ->Speicherbedarf steigt um 5 MB an ->schließe form6 via x-button ->Speicherbedarf sinkt um 4250 Kb( wieder 650 Kb zu wenig). ->wähle ich erneut form2 aus und zeige es an erhöt sich der Speicherbedarf nur noch um 4250 Kb. ->Beim schließen werden dann auch 4250Kb wieder freigegeben. Hoffe das ich das jetzt soweit klären konnte :) @alzaimar Entweder das, oder es wird sich (bei o.g. vorgehen) gewollt etwas gehalten (eben für erneutes anzeigen). |
Re: Memoryleak bei dynamischen Forms ?
Hallo,
OK, jetzt habe sogar ich es verstanden ;) Also der Taskmanager ist nicht wirklich aussagekräftig :) Es kann sein, dass die VCL intern noch etwas cachet gugg dir doch einfach das bissel VCL-Code an ;) Heiko |
Re: Memoryleak bei dynamischen Forms ?
Es kann sein, das der Memorymanager Sachen vorhält, aber mir fällt da eine Anekdote von den Entwicklern des MS-SQL-Servers ein:
Die verzichten voll und ganz auf das Windows-Management (aus eigenem Hause) und haben sich ihr eigenes Memory Management gebastelt. Soweit ich mich erinnere, gibt Windows den Speicher nach gutdünken frei. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:43 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz