Speicher aufräumen
- photor
- Beiträge: 512
- Registriert: Mo 24. Jan 2011, 21:38
- OS, Lazarus, FPC: Arch Linux: L 3.2 (Gtk2) FPC 3.2.2
- CPU-Target: 64Bit
Speicher aufräumen
Hallo Forum,
ich habe die letzte Zeit ein neues Programm erstellt und dabei (um was neues zu lernen) ausgiebig mit Klassen, Listen und Generics hantiert. Das Programm ist relative schnell gewachsen und ich habe sicherlich an einigen Ecken noch schludrigen Code stehen (Funktion ging erstmal vor).
Nun braucht das Programm (aus der IDE gestartet) recht lange (ca. 7 bis 20 sek) vom Quit-Button-Press bis ich wieder in der IDE bin. Meine Vermutung ist, dass da noch einiges im Speicher aufgeräumt werden muss.
Meine Frage: gibt es eine Option oder ein Tool, dass mir hilft, Speicherlecks zu lokalisieren? Oder bleibt mir nur übrig, händisch zu schauen, wo eventuell Speicher händisch freigegeben werden muss und Speicher-Schutz-Blöcke drum rum zu bauen (werde ich sowieso noch machen).
Danke für Eure Tipps.
Ciao,
Photor
ich habe die letzte Zeit ein neues Programm erstellt und dabei (um was neues zu lernen) ausgiebig mit Klassen, Listen und Generics hantiert. Das Programm ist relative schnell gewachsen und ich habe sicherlich an einigen Ecken noch schludrigen Code stehen (Funktion ging erstmal vor).
Nun braucht das Programm (aus der IDE gestartet) recht lange (ca. 7 bis 20 sek) vom Quit-Button-Press bis ich wieder in der IDE bin. Meine Vermutung ist, dass da noch einiges im Speicher aufgeräumt werden muss.
Meine Frage: gibt es eine Option oder ein Tool, dass mir hilft, Speicherlecks zu lokalisieren? Oder bleibt mir nur übrig, händisch zu schauen, wo eventuell Speicher händisch freigegeben werden muss und Speicher-Schutz-Blöcke drum rum zu bauen (werde ich sowieso noch machen).
Danke für Eure Tipps.
Ciao,
Photor
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2817
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: Speicher aufräumen
Na klaro gibt es das. Schau mal hier: https://wiki.freepascal.org/heaptrc
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
- photor
- Beiträge: 512
- Registriert: Mo 24. Jan 2011, 21:38
- OS, Lazarus, FPC: Arch Linux: L 3.2 (Gtk2) FPC 3.2.2
- CPU-Target: 64Bit
Re: Speicher aufräumen
Danke. Das sieht doch schon mal ganz gut aus.
Ciao,
Photor
Ciao,
Photor
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Speicher aufräumen
Spricht das nicht eher dafür, dass der Speicher (allgemeiner: Ressourcen) ordnungsgemäß aufgeräumt wird? Wenn du den Speicher nicht selbst frei gibst, wird das der Memory Manager auch nicht für dich tun.photor hat geschrieben: Di 2. Mär 2021, 16:10 Nun braucht das Programm (aus der IDE gestartet) recht lange (ca. 7 bis 20 sek) vom Quit-Button-Press bis ich wieder in der IDE bin. Meine Vermutung ist, dass da noch einiges im Speicher aufgeräumt werden muss.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
- photor
- Beiträge: 512
- Registriert: Mo 24. Jan 2011, 21:38
- OS, Lazarus, FPC: Arch Linux: L 3.2 (Gtk2) FPC 3.2.2
- CPU-Target: 64Bit
Re: Speicher aufräumen
Das spricht - meiner Meinung nach - dafür, dass da irgendwer den Speicher aufräumt, ja.Socke hat geschrieben: Mi 3. Mär 2021, 11:51 Spricht das nicht eher dafür, dass der Speicher (allgemeiner: Ressourcen) ordnungsgemäß aufgeräumt wird? Wenn du den Speicher nicht selbst frei gibst, wird das der Memory Manager auch nicht für dich tun.

ich fürchte aber, dass das jemand tun muss (weil ich ja in der IDE weiter mache; vermutung Debugger), weil ich es nicht ordnungsgemäß getan habe (den Freiland-Test ohne IDE habe ich noch nicht gemacht).
Also von anderen Programmen kenne ich das so jedenfalls nicht.
Ciao,
Photor
- af0815
- Lazarusforum e. V.
- Beiträge: 6782
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Speicher aufräumen
Ich kenne diese verzögerung wenn Heaptrace eingeschalten ist. Das muss beim Beenden den Speicherbereich untersuchen. Faustregel bei mir ist, je schneller die IDE wieder bereit ist, umso weniger Probleme gibt es mit dem Speicher.
Bekommst du Meldungen von Heaptrace oder in die Kommandozeile oder lässt du in eine Datei schreiben ?!
Bekommst du Meldungen von Heaptrace oder in die Kommandozeile oder lässt du in eine Datei schreiben ?!
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
- photor
- Beiträge: 512
- Registriert: Mo 24. Jan 2011, 21:38
- OS, Lazarus, FPC: Arch Linux: L 3.2 (Gtk2) FPC 3.2.2
- CPU-Target: 64Bit
Re: Speicher aufräumen
Moin,
ich habe jetzt mal heaptrc (nach Wiki) eingeschaltet/aktiviert. Im leakview zeigt sich auch was:
ich denke, mein Verdacht war begründet: da muss ich noch kräftig suchen.
Genauer: die option -gh war sogar schon aktiviert, was vielleicht auch das verzögerte Beenden erklärt. Bloß in eine Datei wurde die Info noch nicht geschrieben. Dazu war dann noch der zusätzliche Code in der .LPR nötig. Die Ausgaben in der Datei bzw. die von heapview muss ich noch zu interpretieren lernen.
Vielen Dank bis hierher. wenn noch Fragen auftauchen, melde ich mich.
Ciao,
Photor
ich habe jetzt mal heaptrc (nach Wiki) eingeschaltet/aktiviert. Im leakview zeigt sich auch was:
Code: Alles auswählen
Total Mem allocated: 4016928
Leaking Mem Size: 33423
Leaking Blocks Count: 699

Genauer: die option -gh war sogar schon aktiviert, was vielleicht auch das verzögerte Beenden erklärt. Bloß in eine Datei wurde die Info noch nicht geschrieben. Dazu war dann noch der zusätzliche Code in der .LPR nötig. Die Ausgaben in der Datei bzw. die von heapview muss ich noch zu interpretieren lernen.
Vielen Dank bis hierher. wenn noch Fragen auftauchen, melde ich mich.
Ciao,
Photor
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Speicher aufräumen
Hi!
Wenn heaptrace ne Menge Fehler findet, kann das echt dauern.
Besonders, wenn der Fehler tief im Source liegt, und so durch die rufenden Funktionen "durchgeschleppt" wird. Da kann es durchaus passieren, dass einem von heaptrc 10 Mal oder öfter eine Code-Zeile für ein und denselben Fehler angezeigt wird, die auf Schlag verschwinden, wenn man den Fehler beseitigt hat.
Bei dem ganzen Gehacke hat man dann endlich Zeit, sich ne Zigarette zu drehen ...
Winni
Wenn heaptrace ne Menge Fehler findet, kann das echt dauern.
Besonders, wenn der Fehler tief im Source liegt, und so durch die rufenden Funktionen "durchgeschleppt" wird. Da kann es durchaus passieren, dass einem von heaptrc 10 Mal oder öfter eine Code-Zeile für ein und denselben Fehler angezeigt wird, die auf Schlag verschwinden, wenn man den Fehler beseitigt hat.
Bei dem ganzen Gehacke hat man dann endlich Zeit, sich ne Zigarette zu drehen ...
Winni
-
- Lazarusforum e. V.
- Beiträge: 367
- Registriert: So 5. Mai 2019, 16:52
- OS, Lazarus, FPC: ArchLinux und Windows mit FPCUPdeluxe (L: 3.6, FPC 3.2.2)
- CPU-Target: x86_64, i386
- Wohnort: Bayreuth
Re: Speicher aufräumen
Und wenn man nicht raucht?Bei dem ganzen Gehacke hat man dann endlich Zeit, sich ne Zigarette zu drehen ...


Allerdings hab ich manchmal den Fehler auch nicht gefunden. In der Arbeit hab ich so ein Programm wo ich so einen Fehler habe. Mir wird zwar die Zeile im Hauptprogramm angezeigt, aber dort befindet sich ein Free. Manchmal wäre ich echt froh, wenn Pascal einfach etwas gesprächiger wäre.

Tipp für PostgreSQL: www.pg-forum.de
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Speicher aufräumen
Hi!
Ja - indeed. Ich hab mich manchmal auch schon blöd gesucht.
Wenn heaptrc auf "free" verweist:
Kann es sein dass Du das Object zweimal created hast??
Das war es mal bei mir mit einer BGRAbitmap.
Winni
Ja - indeed. Ich hab mich manchmal auch schon blöd gesucht.
Wenn heaptrc auf "free" verweist:
Kann es sein dass Du das Object zweimal created hast??
Das war es mal bei mir mit einer BGRAbitmap.
Winni
-
- Lazarusforum e. V.
- Beiträge: 367
- Registriert: So 5. Mai 2019, 16:52
- OS, Lazarus, FPC: ArchLinux und Windows mit FPCUPdeluxe (L: 3.6, FPC 3.2.2)
- CPU-Target: x86_64, i386
- Wohnort: Bayreuth
Re: Speicher aufräumen
Leider nicht. Nächste Woche noch mal genauer suchen...Kann es sein dass Du das Object zweimal created hast??
Das war es mal bei mir mit einer BGRAbitmap
Tipp für PostgreSQL: www.pg-forum.de
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1647
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: Speicher aufräumen
Normalerweise zeigt heaptrc doch an wo der Speicher allokiert wurde?
- Winni
- Beiträge: 1577
- Registriert: Mo 2. Mär 2009, 16:45
- OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
- CPU-Target: 64Bit
- Wohnort: Fast Dänemark
Re: Speicher aufräumen
Hi!
Wie fies die Suche sein kann, zeige ich hier mal am Beispiel.
Ich hab eine selbst geschriebene Function BGRArotate90, die eine Spielkarte um 90 Grad dreht.
In der Function wird eine temporäre Bitmap namens tmp benutzt. Die gebe ich jetzt mal vorsätzlich nicht frei, um ein Leck zu erzeugen.
Der erste Verweis zeigt auf Zeile 325, die da lautet:
Dass nun der Fehler in BGRArotate90 steckt, geht aus dem Log von heaptrc nicht hervor.
Im Gegenteil: er zeigt auch noch die "unschuldigen" function an, die das Leck mit durchschleppen:
LOADKDEDECK, line 325 of skat1.pas
FORMCREATE, line 974 of skat1.pas
DOCREATE, line 939 of include/customform.inc
AFTERCONSTRUCTION, line 149 of include/customform.inc
Und hier nun der ganze Salat, der durch ein einziges vergessenes tmp.free von heaptrc erzeugt wird
Heap dump by heaptrc unit of /home/winni/skat/skat
3986 memory blocks allocated : 13037921/13045544
3983 memory blocks freed : 13000433/13008056
3 unfreed memory blocks : 37488
True heap size : 1376256
True free heap : 1338112
Should be : 1338192
Call trace for block $00007F0FB12A0D50 size 36864
$0000000000824EDD
$00000000007D2552
$00000000007DF035
$00000000007AF095
$00000000007D2006
$00000000007DEA7D
$00000000007AED7D
$00000000007AD9BA
$00000000007DE9E4
$00000000007AECE4
$00000000007AD97A
$00000000007AE12A
$00000000004646A6 LOADKDEDECK, line 325 of skat1.pas
$00000000004674AD FORMCREATE, line 974 of skat1.pas
$000000000044EE47 DOCREATE, line 939 of include/customform.inc
$000000000044CABD AFTERCONSTRUCTION, line 149 of include/customform.inc
Call trace for block $00007F0FB51489E0 size 144
$00000000007B56A9
$00000000007D1FEB
$00000000007DEA7D
$00000000007AED7D
$00000000007AD9BA
$00000000007DE9E4
$00000000007AECE4
$00000000007AD97A
$00000000007AE12A
$00000000004646A6 LOADKDEDECK, line 325 of skat1.pas
$00000000004674AD FORMCREATE, line 974 of skat1.pas
$000000000044EE47 DOCREATE, line 939 of include/customform.inc
$000000000044CABD AFTERCONSTRUCTION, line 149 of include/customform.inc
$0000000000455634 CREATE, line 3184 of include/customform.inc
$000000000045F955 CREATEFORM, line 2239 of include/application.inc
$000000000041F05E main, line 19 of skat.lpr
Call trace for block $00007F0FB134EA70 size 480
$00000000007B56A9
$00000000007D1FEB
$00000000007DEA7D
$00000000007AED7D
$00000000007AD9BA
$00000000007DE9E4
$00000000007AECE4
$00000000007AD97A
$00000000007AE12A
$00000000004646A6 LOADKDEDECK, line 325 of skat1.pas
$00000000004674AD FORMCREATE, line 974 of skat1.pas
$000000000044EE47 DOCREATE, line 939 of include/customform.inc
$000000000044CABD AFTERCONSTRUCTION, line 149 of include/customform.inc
$0000000000455634 CREATE, line 3184 of include/customform.inc
$000000000045F955 CREATEFORM, line 2239 of include/application.inc
$000000000041F05E main, line 19 of skat.lpr
Winni
Wie fies die Suche sein kann, zeige ich hier mal am Beispiel.
Ich hab eine selbst geschriebene Function BGRArotate90, die eine Spielkarte um 90 Grad dreht.
In der Function wird eine temporäre Bitmap namens tmp benutzt. Die gebe ich jetzt mal vorsätzlich nicht frei, um ein Leck zu erzeugen.
Der erste Verweis zeigt auf Zeile 325, die da lautet:
Code: Alles auswählen
back90 := BGRArotate90(back,true);
Im Gegenteil: er zeigt auch noch die "unschuldigen" function an, die das Leck mit durchschleppen:
LOADKDEDECK, line 325 of skat1.pas
FORMCREATE, line 974 of skat1.pas
DOCREATE, line 939 of include/customform.inc
AFTERCONSTRUCTION, line 149 of include/customform.inc
Und hier nun der ganze Salat, der durch ein einziges vergessenes tmp.free von heaptrc erzeugt wird
Heap dump by heaptrc unit of /home/winni/skat/skat
3986 memory blocks allocated : 13037921/13045544
3983 memory blocks freed : 13000433/13008056
3 unfreed memory blocks : 37488
True heap size : 1376256
True free heap : 1338112
Should be : 1338192
Call trace for block $00007F0FB12A0D50 size 36864
$0000000000824EDD
$00000000007D2552
$00000000007DF035
$00000000007AF095
$00000000007D2006
$00000000007DEA7D
$00000000007AED7D
$00000000007AD9BA
$00000000007DE9E4
$00000000007AECE4
$00000000007AD97A
$00000000007AE12A
$00000000004646A6 LOADKDEDECK, line 325 of skat1.pas
$00000000004674AD FORMCREATE, line 974 of skat1.pas
$000000000044EE47 DOCREATE, line 939 of include/customform.inc
$000000000044CABD AFTERCONSTRUCTION, line 149 of include/customform.inc
Call trace for block $00007F0FB51489E0 size 144
$00000000007B56A9
$00000000007D1FEB
$00000000007DEA7D
$00000000007AED7D
$00000000007AD9BA
$00000000007DE9E4
$00000000007AECE4
$00000000007AD97A
$00000000007AE12A
$00000000004646A6 LOADKDEDECK, line 325 of skat1.pas
$00000000004674AD FORMCREATE, line 974 of skat1.pas
$000000000044EE47 DOCREATE, line 939 of include/customform.inc
$000000000044CABD AFTERCONSTRUCTION, line 149 of include/customform.inc
$0000000000455634 CREATE, line 3184 of include/customform.inc
$000000000045F955 CREATEFORM, line 2239 of include/application.inc
$000000000041F05E main, line 19 of skat.lpr
Call trace for block $00007F0FB134EA70 size 480
$00000000007B56A9
$00000000007D1FEB
$00000000007DEA7D
$00000000007AED7D
$00000000007AD9BA
$00000000007DE9E4
$00000000007AECE4
$00000000007AD97A
$00000000007AE12A
$00000000004646A6 LOADKDEDECK, line 325 of skat1.pas
$00000000004674AD FORMCREATE, line 974 of skat1.pas
$000000000044EE47 DOCREATE, line 939 of include/customform.inc
$000000000044CABD AFTERCONSTRUCTION, line 149 of include/customform.inc
$0000000000455634 CREATE, line 3184 of include/customform.inc
$000000000045F955 CREATEFORM, line 2239 of include/application.inc
$000000000041F05E main, line 19 of skat.lpr
Winni
Re: Speicher aufräumen
Gibt es in der Entwicklungsumgebung ein Tool, dass auf fehlende ".free" hinweißt? (o.ä.)
Damit könnte man doch einfacher solche lecks finden oder?!
Damit könnte man doch einfacher solche lecks finden oder?!
- af0815
- Lazarusforum e. V.
- Beiträge: 6782
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Speicher aufräumen
Woher sollte ein Tool wissen, wo ein .Free benötigt wird ?
Das wäre nur eine Raterei, weil Objekte können an allen Stellen erzeugt bzw. ge-freed werden. Auch Kopien und Referenzen sind zulässig. Das würde dann so wie bei SQL funktionieren, einfache Sachen (wo ich das ganze nicht brauche) würden funktionieren. Wenn es komplizierter wird, so funktioniert die automatische Logik nicht.
Nein Heaptrace ist schon in Ordnung. NUR die meisten fangen OHNE die richtigen Debugeinstellungen an. Wenn ich ein Projekt hochziehe so gibt es ein paar fixe Sachen. Und dazu gehört, das ich einen Debug und einen Release Modus habe. Im Debug wird programmiert und dort auch gnadenlos heaptrace und die anderen Debugeinstellungen verwendet. Jedes Warning wird entweder im Code lokal deaktiviert (wenn ich genau weis warum) oder behoben. Damit schleicht sich schon mal kein schlechter Stil ein und kleine Fahrlässigkeiten fallen auf. Release ist dann vorbehalten, wenn es wirklich raus geht. Dort wird alles auf ein nötiges Mass zurückgefahren. Generell verwende ich auch den LazLogger und jede Exception (ob geplant oder ungeplant) lässt sich so zumindest erkennen, wenn die Kommandozeilenoption verwendet wird. Damit kann ich dann den Kunden mal ersuchen, das ganze mit der option LazLogger zu starten und kann erkennen, warum da ev. was schief läuft.
Konklusio: Wenn man am Anfang gleich konsequent ist, braucht man später weniger suchen
Das wäre nur eine Raterei, weil Objekte können an allen Stellen erzeugt bzw. ge-freed werden. Auch Kopien und Referenzen sind zulässig. Das würde dann so wie bei SQL funktionieren, einfache Sachen (wo ich das ganze nicht brauche) würden funktionieren. Wenn es komplizierter wird, so funktioniert die automatische Logik nicht.
Nein Heaptrace ist schon in Ordnung. NUR die meisten fangen OHNE die richtigen Debugeinstellungen an. Wenn ich ein Projekt hochziehe so gibt es ein paar fixe Sachen. Und dazu gehört, das ich einen Debug und einen Release Modus habe. Im Debug wird programmiert und dort auch gnadenlos heaptrace und die anderen Debugeinstellungen verwendet. Jedes Warning wird entweder im Code lokal deaktiviert (wenn ich genau weis warum) oder behoben. Damit schleicht sich schon mal kein schlechter Stil ein und kleine Fahrlässigkeiten fallen auf. Release ist dann vorbehalten, wenn es wirklich raus geht. Dort wird alles auf ein nötiges Mass zurückgefahren. Generell verwende ich auch den LazLogger und jede Exception (ob geplant oder ungeplant) lässt sich so zumindest erkennen, wenn die Kommandozeilenoption verwendet wird. Damit kann ich dann den Kunden mal ersuchen, das ganze mit der option LazLogger zu starten und kann erkennen, warum da ev. was schief läuft.
Konklusio: Wenn man am Anfang gleich konsequent ist, braucht man später weniger suchen

Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).