![]() |
Programm belegt immer mehr Speicher
Hallo,
in anderen Threads habe ich ja eine Lösung gesucht und jetzt auch eingebaut, PlugIns nach der Benutzung wieder freizugeben. Diese PlugIns sind DLL-Forms. Beim Laden speicher ich in ein Array den Titel, das Handle und den Pfad zur DLL. Wenn ich die DLL lade, wird der Hauptprozess im Speicher um ca 2MB größer. Soweit ist das auch ok. Wenn ich das PlugIn wieder entlade, schrumpft das Programm nicht auf seine ursprüngliche Größe, sondern es bleibt 200kb größer. Öffne ich das PlugIn nochmal, wird es wieder um 160kb größer. Beim nächsten Öffen und Schließen des PlugIns wird der Hauptprozess um 80kb größer usw... d.h, das Programm wird ständig um eine kleiner werdene Größe größer :-D (Der Satz gefällt mir). Woran kann sowas liegen? |
Re: Programm belegt immer mehr Speicher
Ein kleiner Teil davon liegt an einem Fehler in Delphi das DLL's nicht wirklich 100%ig entladen werden. Müsste auch irgendwo in QC oder DN-Seite bei Codegear beschrieben sein.
|
Re: Programm belegt immer mehr Speicher
Wie groß ist ungefähr ein kleiner Teil? Werden diese nicht genutzten Speicheblöcke (?) von Windows nach einer gewissen Zeit wieder freigegeben, also sozusagen: Räumt Windows den Speicher selbst wieder auf?
|
Re: Programm belegt immer mehr Speicher
Hallo,
wie sieht es denn aus mit fastmm oder memcheck ? Hast du damit mal nach Lecks gesucht ? Heiko |
Re: Programm belegt immer mehr Speicher
Davor hab ich immer Angst :P
Ne, das ist eine gute Idee. Das kann ich mal machen. Aber das eine PlugIn, mit dem ich das getestet habe, hat nur ein INI-Object und einmal die ZQuery und ZConnection... Mal sehen. |
Re: Programm belegt immer mehr Speicher
Hm...
wie kann ich denn mein PlugIn mit FastMM4 prüfen? Ich hab die Unit in die Projekt-Unit (erste Unit) eingebunden und er zeigt mir KEINE Fehler an, obwohl ich einen eingebaut habe. Im Hauptprogramm funktioniert die Fehlerprüfung (war nur einer!!!). Doch die DLLs werden ja vom Programm ge- und entladen. Muss ich noch was spezielles einstellen? |
Re: Programm belegt immer mehr Speicher
Kann es auch sein, dass die erstellten Forms in der DLL nicht richtig freigegeben werden? Ich mache das so:
Delphi-Quellcode:
Ist das richtig?
PlugInName.FreeForms;
FreeLibrary(DLLHandle); //In der DLL: procedure TMeinPlugIn.CreateForms; begin Form1:=TForm1.Create(nil); end; procedure TMeinPlugIn.FreeForms; begin FreeAndNil(Form1); end; |
Re: Programm belegt immer mehr Speicher
Hallo,
bei memcheck gibt es einen Aufruf (meminit), den packst du in die library unit über begin Meminit // oder so ähnlich end; |
Re: Programm belegt immer mehr Speicher
Hallo,
ich habe MemCheck eingebeunden. Er findet SpeicherLecks in FindUtils.pas und bricht dann mein ganzes Projekt ab. Ist das richtig? Es kommt eine AV, dann die Log-File von MemCheck und dann wird mein Programm beendet. Hier mal die Log: Zitat:
|
Re: Programm belegt immer mehr Speicher
Hallo,
das ist jetzt mal ein "Nebeneffekt", durch die Schutzverletzung wird Exception-Speicher nicht freigegeben. Die Schutzverletzung weist auf einen Fehler bei dir im Speicher-Management hin. Der Memcheck-Memory-Manager ersetzt ja den internen von Codegear, und der ist pingeliger als der alte. Die Schutzverletzung muss natürlich raus .. ;) Wenn du memcheck in der IDE laufen lässt und ein "normales" speicherleck gefunden wird, wirdnach dem Programmende über eine Exeption genau an die Stelle gesprungen, wo der Speicher erzeugt wird, also z.B. myObject:= TObject.Create; Ist manchmal ganz sinnvoll, ich unterbreche das dann aber über Strl+F2. Dann wird das Log direkt angezeigt (wie du hier gerade siehst). Heiko |
Re: Programm belegt immer mehr Speicher
Hm,
aber woher weiß ich, an welcher Stelle die AV auftritt? Er sagt ja, dass einige Lecks in der SysUtils sind. FastMM4 und der con CodeGear haben nichts gefunden. |
Re: Programm belegt immer mehr Speicher
Hallo
" ich habe MemCheck eingebeunden. Er findet SpeicherLecks in FindUtils.pas und bricht dann mein ganzes Projekt ab. Ist das richtig? Es kommt eine AV, dann die Log-File von MemCheck und dann wird mein Programm beendet. Hier mal die Log: " Die Schutzverletzung musst du natürlich suchen, also Debugger anwerfen und los! Im Log steht SysUtils, nicht FindUtils (?) Durch die AV wird das Programm beendet, MemCheck zeigt dann die bisher gefundenen Lecks an, in deinem Leck sind das aber "nur" die Lecks durch die Exceptiomn bei der AV selber. Drück mal F7, wenn die Schutzverletzung kommt, dann springt er meistens in die Nähe des verursachenden Codes. Du könntest auch mal madexcept probieren, dann aber das memcheck auskommentieren. Heiko |
Re: Programm belegt immer mehr Speicher
Hallo,
bin immernoch auf der Suche nach den "Lecks". Hab jetzt rausgefunden, dass jede dynamisch erstellte Form 26kb nach dem free hinterlässt. Das macht bei 4 forms 104kb. Dazu kommen noch 4-12kb, die beim FreeLibrary übrig bleiben. Ist das richtig? Es passiert folgendes: 1. Hauptprogramm wird geladen. 2. Ein PlugIn wird durch den Nutzer geladen. (Dazu der Code)
Delphi-Quellcode:
3. PlugIn wird irgendwann wieder beendet. (Dazu der Code)
PlugIn:
procedure TKalender.CreateForms; begin Form1:=TForm1.Create(nil); Form2:=TForm2.Create(nil); Form3:=TForm3.Create(nil); Form4:=TForm4.Create(nil); end;
Delphi-Quellcode:
4. Das Hauptprogramm schließt das PlugIn
PostMessage(FindWindow(nil, 'Mein Hauptprogramm), WM_UNLOADPLUGIN, HInstance, 0);
Delphi-Quellcode:
5. Die Prozedur FreeForms im PlugIn sieht so aus:
procedure TForm2.UnloadPlugIn(var msg: TMessage);
var hndl: Integer; i: Integer; begin hndl:= msg.WParam; for i:=0 to High(PJPlugIn) do begin if(PJPlugIn[i].PlugInHandle = hndl) then begin PJPlugIn[i].PlugInName.FreeForms; FreeLibrary(PJPlugIn[i].PlugInHandle); PJPlugIn[i].PlugInTitel:=''; PJPlugIn[i].PlugInFile:=''; PJPlugIn[i].PlugInName:=nil; PJPlugIn[i].PlugInHandle:=0; end; end; PJPlugIn:=nil; end;
Delphi-Quellcode:
Mach ich da was falsch? Es sind alle Komponenten in den Forms freigegeben. Wenn ich ein neues PlugIn mit einer Form erstelle, bleiben 26kb übrig.
Form1.Free;
Form2.Free; Form3.Free; Form4.Free; Danke |
Re: Programm belegt immer mehr Speicher
Hallo,
ich würde erst mal deine Form-Variablen prüfen, deine Hauptform-Variable heisst Form2, einer der Plugin-Vars auch. Ich benutze prinzipiell nicht die von der IDE angelegten Variablen, sondern (meistens) lokale,in der Art
Delphi-Quellcode:
Da du wohl die 4 Forms gleichzeitig brauchst,
procedure ExecForm_About;
var Form: TForm_About; begin Form:= TForm_About.Create(NIL); try Form.ShowModal; finally Form.Free; end; end; packst du die in deine TKalenderklasse als Klassen-Variablen. Aber bitte mit richtigen Namen. Dann schnappe dir memcheck (das kann auch Dlls prüfen). Ausserdem prüfe mal, ob deine TFormX (argz ;)) .destroy wirklich aufgerufen wird z.B. mit einer MessageBox. Hm, etwas ist mir noch aufgefallen. PJPlugIn:= NIL; Wie ist PJPlugIn definiert ? Was soll diese Zeile machen ? Falls es ein dynamisches array ist, würde ich mal nen SetLength(PJPlugIn, 0); davor setzen, oder ein FreeAndNIL. Mit dynamischen arrays kenne ich mich aber nicht aus, ich benutze immer TList. Heiko |
Re: Programm belegt immer mehr Speicher
Danke. Das werde ich mal ausprobieren.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:20 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