Programm braucht ständig mehr Speicher - Lazarus unter Raspi
-
- Beiträge: 1224
- Registriert: So 20. Mär 2016, 22:14
- OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
- CPU-Target: Raspberry Pi 3
Programm braucht ständig mehr Speicher - Lazarus unter Raspi
Ich habe mein erstes Programm mit Lazarus /FPC auf dem Raspi 3 erstellt. Ein Portscanner für die GPIOs. Funktioniert soweit, allerdings habe ich festgestellt, daß das Programm mit der Zeit immer mehr Speicher benötigt und die Prozessorlast in die Höhe treibt.
Anfangs: CPU 0-2%, RSS 22.9M, Speicher 32.8M
nach 6 Stunden: CPU 24%, RSS 44.3M, Speicher 54.2M
Woran kann das liegen?
Das Programm erstellt eine GUI mit TToggleBoxen und einen Timer. Dann scannt es alle 100msec die GPIOs in /sys/class/gpio und zeigt die aktiven GPIOs als Zustand der Toggleboxen an. Durch Klick auf die Toggles kann man GPIOs aktivieren oder den Zustand ändern. Das funktioniert auch wunderbar.
Ich habe schon verschiedene Programmfunktionen auskommentiert (z.B. den Scan alle 100msec), und auch ohne Userinteraktion wächst der Speicherbedarf kontinuierlich. Es sind etwa 1kByte pro Sekunde. Ich finde es einfach nicht.
Anbei die Sourcen und die Exe. Leider kann ich die Sourcen nicht als Codeblock einbetten, wahrscheinlich zu lang.
Ich bitte die häßliche Abfrage der Toggleboxen mit der IF-Schlange zu entschuldigen, das geht sicher eleganter, aber ich habe keine Möglichkeit gefunden. Ich bin aber nach 20 Jahren Abstinanz auch erst seit einer Woche wieder mit Pascal zugange.
Anfangs: CPU 0-2%, RSS 22.9M, Speicher 32.8M
nach 6 Stunden: CPU 24%, RSS 44.3M, Speicher 54.2M
Woran kann das liegen?
Das Programm erstellt eine GUI mit TToggleBoxen und einen Timer. Dann scannt es alle 100msec die GPIOs in /sys/class/gpio und zeigt die aktiven GPIOs als Zustand der Toggleboxen an. Durch Klick auf die Toggles kann man GPIOs aktivieren oder den Zustand ändern. Das funktioniert auch wunderbar.
Ich habe schon verschiedene Programmfunktionen auskommentiert (z.B. den Scan alle 100msec), und auch ohne Userinteraktion wächst der Speicherbedarf kontinuierlich. Es sind etwa 1kByte pro Sekunde. Ich finde es einfach nicht.
Anbei die Sourcen und die Exe. Leider kann ich die Sourcen nicht als Codeblock einbetten, wahrscheinlich zu lang.
Ich bitte die häßliche Abfrage der Toggleboxen mit der IF-Schlange zu entschuldigen, das geht sicher eleganter, aber ich habe keine Möglichkeit gefunden. Ich bin aber nach 20 Jahren Abstinanz auch erst seit einer Woche wieder mit Pascal zugange.
-
- Beiträge: 565
- Registriert: So 26. Aug 2012, 09:03
- OS, Lazarus, FPC: Windows(10), Linux(Arch)
- CPU-Target: 64Bit
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
Hab grade keine Zeit mich durch irgendwelche sourcen zu wühlen, aber wenn ein Programm immer mehr Speicher frisst, dann hast du vermutlich irgendwo ein Memory Leak.
Probier mal in den Projekteinstellungen heaptrc zu aktivieren. Heaptrc gibt dir wenn du das Programm beendest aus, wo im Sourcecode Speicher belegt, aber nicht mehr freigegeben wurde.
MFG
Komoluna
Probier mal in den Projekteinstellungen heaptrc zu aktivieren. Heaptrc gibt dir wenn du das Programm beendest aus, wo im Sourcecode Speicher belegt, aber nicht mehr freigegeben wurde.
MFG
Komoluna
Programmer: A device to convert coffee into software.
Rekursion: siehe Rekursion.
Rekursion: siehe Rekursion.
-
- Beiträge: 958
- Registriert: Mo 11. Sep 2006, 22:56
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
heaptrc und leakview helfen dir bestimmt
http://wiki.freepascal.org/leakview
grob gesagt Paket leakview installieren
heaptrc Optinon in Lazarus aktivieren
Die Codezeilen aus dem Wiki wohin das Heaptrc file soll zu deiner lpr hinzufügen
Projekt ausführen
File mit Leakview öffnen
http://wiki.freepascal.org/leakview
grob gesagt Paket leakview installieren
heaptrc Optinon in Lazarus aktivieren
Die Codezeilen aus dem Wiki wohin das Heaptrc file soll zu deiner lpr hinzufügen
Projekt ausführen
File mit Leakview öffnen
-
- Beiträge: 1224
- Registriert: So 20. Mär 2016, 22:14
- OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
- CPU-Target: Raspberry Pi 3
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
Ich bin zwar mit heaptrc nicht weitergekommen, aber habe es durch Variationen im Programm eingrenzen können:
Timer von 100msec auf 10sec => Speicher akkumuliert 100 mal langsamer. Oha.
Letztlich ist es der Eintrag in die Statusbar, der einen "Scanner"-Balken erzeugt:
Ich habe den Timer auf 20msec gesetzt, um schneller zu einem Ergebnis zu kommen. Aber jetzt wird es richtig komisch:
- Mit dem Scannerbalken - es wird ein String aus "I" variabler Anzahl von 0 bis 10 geschrieben - erhöht sich der Speicherbedarf kontinuierlich.
- Mit einem festen String aus 10 Zeichen erhöht sich der Speicherbedarf nicht.
- Fülle ich den Scannerstring mit Leerzeichen auf 10 Zeichen auf, erhöht sich der Speicherbedarf kontinuierlich.
- Auch die Uhrzeit mit 8 Zeichen, sekündlich wechselnd, erhöht den Speicherbedarf offenbar nicht (merklich).
- Die Uhrzeit mit Millisekunden (hh:nn:ss.zzz) ausgegeben, erhöht den Speicherbedarf aber sowas von kontinuierlich, stärker noch als der Scannerbalken.
=> obwohl jedesmal die Strings alle 20msec neu übergeben werden.
Es scheint also, daß wechselnde Ausgaben an den Statusbar den Speicherbedarf hochtreiben. Da wird anscheinend jedesmal ein Buffer beschrieben, der dann nicht freigegeben wird.
Oder muß ich die Statusbar anders ansprechen?
Timer von 100msec auf 10sec => Speicher akkumuliert 100 mal langsamer. Oha.
Letztlich ist es der Eintrag in die Statusbar, der einen "Scanner"-Balken erzeugt:
Code: Alles auswählen
procedure Tw_main.t_timerTimer(Sender: TObject);
var
txt : string;
const
scan : integer = 0;
begin
txt := TimeToStr(Now);
g_status.Panels[0].Text := txt;
scan += 1;
If scan >= 10 then scan := -10;
txt := StringOfChar('I', Abs(scan));
g_status.Panels[1].Text := txt; // <= hier ist der Übeltäter
// ScanGpio(); // alle Pins einlesen
end;
- Mit dem Scannerbalken - es wird ein String aus "I" variabler Anzahl von 0 bis 10 geschrieben - erhöht sich der Speicherbedarf kontinuierlich.
- Mit einem festen String aus 10 Zeichen erhöht sich der Speicherbedarf nicht.
- Fülle ich den Scannerstring mit Leerzeichen auf 10 Zeichen auf, erhöht sich der Speicherbedarf kontinuierlich.
- Auch die Uhrzeit mit 8 Zeichen, sekündlich wechselnd, erhöht den Speicherbedarf offenbar nicht (merklich).
- Die Uhrzeit mit Millisekunden (hh:nn:ss.zzz) ausgegeben, erhöht den Speicherbedarf aber sowas von kontinuierlich, stärker noch als der Scannerbalken.
=> obwohl jedesmal die Strings alle 20msec neu übergeben werden.
Es scheint also, daß wechselnde Ausgaben an den Statusbar den Speicherbedarf hochtreiben. Da wird anscheinend jedesmal ein Buffer beschrieben, der dann nicht freigegeben wird.
Oder muß ich die Statusbar anders ansprechen?
-
- Beiträge: 958
- Registriert: Mo 11. Sep 2006, 22:56
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
Das hier wäre noch ein Tip für Profiling unter Linux
http://lazarusroad.blogspot.de/2007/09/ ... e-fpc.html
http://lazarusroad.blogspot.de/2007/09/ ... e-fpc.html
-
- Beiträge: 1224
- Registriert: So 20. Mär 2016, 22:14
- OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
- CPU-Target: Raspberry Pi 3
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
Nun, es ist definitiv der Statusbar. Da brauche ich nicht weiter zu suchen.
Workaround: Je ein TStaticText-Feld zugefügt, die Ausgaben auf tstatictext.Caption geschrieben: Gleiches Problem, Speicher wird hochgezogen.
Ok, versuchen wir ein TLabel, die Ausgaben in tlabel.Caption geschrieben: Speicherbedarf bleibt konstant. Über inzwischen 12 Stunden kein Speicherzuwachs.
Da scheint mir ein kleines Problem bei den Gadgets zu bestehen. Ein Fall für einen Bugreport?
Workaround: Je ein TStaticText-Feld zugefügt, die Ausgaben auf tstatictext.Caption geschrieben: Gleiches Problem, Speicher wird hochgezogen.
Ok, versuchen wir ein TLabel, die Ausgaben in tlabel.Caption geschrieben: Speicherbedarf bleibt konstant. Über inzwischen 12 Stunden kein Speicherzuwachs.
Da scheint mir ein kleines Problem bei den Gadgets zu bestehen. Ein Fall für einen Bugreport?
-
- Beiträge: 1224
- Registriert: So 20. Mär 2016, 22:14
- OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
- CPU-Target: Raspberry Pi 3
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
Ich greife das hier nochmal auf. Ich habe jetzt wieder ein Programm, in dem die Zeit ständig aktualisiert wird, und das akkumuliert auf dem Raspberry (Raspbian Jessie 4.4.9, Lazarus 1.6, FPC 3.0.0) kontinuierlich Speicher.
Ich habe das jetzt mal auf ein TStaticText-Objekt reduziert, in das per Timer alle 10msec ein String geschrieben wird. Das Programm (compiliert) startet mit etwas 18MByte laut Taskmanager, und zieht dann zusehends Speicher an.
Unter Windows braucht die exe im Speicher etwa 2.5MByte und das bleibt konstant.
Kann jemand nachvollziehen, wie sich das Progrämmchen unter anderen Linux-Versionen verhält? Und vor allem, warum wird da immer mehr Speicher gezogen?
Ich habe das jetzt mal auf ein TStaticText-Objekt reduziert, in das per Timer alle 10msec ein String geschrieben wird. Das Programm (compiliert) startet mit etwas 18MByte laut Taskmanager, und zieht dann zusehends Speicher an.
Unter Windows braucht die exe im Speicher etwa 2.5MByte und das bleibt konstant.
Kann jemand nachvollziehen, wie sich das Progrämmchen unter anderen Linux-Versionen verhält? Und vor allem, warum wird da immer mehr Speicher gezogen?
- corpsman
- Lazarusforum e. V.
- Beiträge: 1617
- Registriert: Sa 28. Feb 2009, 08:54
- OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
- CPU-Target: 64Bit
- Wohnort: Stuttgart
- Kontaktdaten:
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
also auf nem Odroid U3 mit FPC 2.6.2 wächst der Speicherverbrauch laut Taskmanager auch ich würde sagen ca 0,5MB pro minute
--
Just try it
Just try it
-
- Beiträge: 958
- Registriert: Mo 11. Sep 2006, 22:56
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
mach in nem Terminal
watch free -m
und beobachte mal die Werte
-/+ buffers/cache: used und free
nachdem du dein Programm gestartet hast
edit:
hmm
Sa 7. Jan 16:58:50 CET 2017
_____________________________ Swap USS PSS RSS
/home/pi/Public/memleak/mem 0 14808 17104 27704
Sa 7. Jan 17:49:45 CET 2017
/home/pi/Public/memleak/mem 0 33604 35901 46500
da läuft Speicher aus
watch free -m
und beobachte mal die Werte
-/+ buffers/cache: used und free
nachdem du dein Programm gestartet hast
edit:
hmm
Sa 7. Jan 16:58:50 CET 2017
_____________________________ Swap USS PSS RSS
/home/pi/Public/memleak/mem 0 14808 17104 27704
Sa 7. Jan 17:49:45 CET 2017
/home/pi/Public/memleak/mem 0 33604 35901 46500
da läuft Speicher aus
-
- Beiträge: 1224
- Registriert: So 20. Mär 2016, 22:14
- OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
- CPU-Target: Raspberry Pi 3
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
Unter welchem Linux hast Du das getestet?creed steiger hat geschrieben:da läuft Speicher aus
-
- Beiträge: 958
- Registriert: Mo 11. Sep 2006, 22:56
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
RaspbianTimm Thaler hat geschrieben:Unter welchem Linux hast Du das getestet?creed steiger hat geschrieben:da läuft Speicher aus
-
- Beiträge: 1224
- Registriert: So 20. Mär 2016, 22:14
- OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
- CPU-Target: Raspberry Pi 3
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
Der Witz ist jetzt: Ändere ich die Klasse des TStaticText in ein TLabel (BorderStyle muss dabei entfernt werden), braucht das Programm anstatt von 8% CPU nur noch 4% - und der Speicherbedarf steht bei 17.9MB festgenagelt.
Es liegt also ziemlich sicher am TStaticText, allerdings ist mir das - siehe oben - bei einer Statusbar auch schon aufgefallen. Vielleicht benutzen die die gleichen Routinen.
Spätestens wenn man ständig aktualisierte Messwerte mit TStaticText anzeigen will und dabei noch mehrere Anzeigen hat dürfte das auf Dauer Probleme machen.
Es liegt also ziemlich sicher am TStaticText, allerdings ist mir das - siehe oben - bei einer Statusbar auch schon aufgefallen. Vielleicht benutzen die die gleichen Routinen.
Spätestens wenn man ständig aktualisierte Messwerte mit TStaticText anzeigen will und dabei noch mehrere Anzeigen hat dürfte das auf Dauer Probleme machen.
-
- Beiträge: 958
- Registriert: Mo 11. Sep 2006, 22:56
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
Ich werds morgen vielleicht mal mit Qt probieren, das war mit GTK.
Nicht das es am Widgetset liegt.
Nicht das es am Widgetset liegt.
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
Wird es wohl, da unter Windows kein Speicherzuwachs zu sehen ist.creed steiger hat geschrieben:Nicht das es am Widgetset liegt.
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
-
- Beiträge: 1224
- Registriert: So 20. Mär 2016, 22:14
- OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
- CPU-Target: Raspberry Pi 3
Re: Programm braucht ständig mehr Speicher - Lazarus unter R
Ich würds auch gern testen, wie änderst Du das Widgetset in Lazarus unter Raspbian?creed steiger hat geschrieben:Ich werds morgen vielleicht mal mit Qt probieren, das war mit GTK.