Programm braucht ständig mehr Speicher - Lazarus unter Raspi

Rund um die LCL und andere Komponenten
Timm Thaler
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

Beitrag von Timm Thaler »

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.

GPIO-01.png

Komoluna
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

Beitrag von Komoluna »

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
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

creed steiger
Beiträge: 957
Registriert: Mo 11. Sep 2006, 22:56

Re: Programm braucht ständig mehr Speicher - Lazarus unter R

Beitrag von creed steiger »

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

Timm Thaler
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

Beitrag von Timm Thaler »

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:

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;


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?

creed steiger
Beiträge: 957
Registriert: Mo 11. Sep 2006, 22:56

Re: Programm braucht ständig mehr Speicher - Lazarus unter R

Beitrag von creed steiger »

Das hier wäre noch ein Tip für Profiling unter Linux

http://lazarusroad.blogspot.de/2007/09/ ... e-fpc.html

Timm Thaler
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

Beitrag von Timm Thaler »

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?

Timm Thaler
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

Beitrag von Timm Thaler »

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?

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
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

Beitrag von corpsman »

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

creed steiger
Beiträge: 957
Registriert: Mo 11. Sep 2006, 22:56

Re: Programm braucht ständig mehr Speicher - Lazarus unter R

Beitrag von creed steiger »

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

Timm Thaler
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

Beitrag von Timm Thaler »

creed steiger hat geschrieben:da läuft Speicher aus


Unter welchem Linux hast Du das getestet?

creed steiger
Beiträge: 957
Registriert: Mo 11. Sep 2006, 22:56

Re: Programm braucht ständig mehr Speicher - Lazarus unter R

Beitrag von creed steiger »

Timm Thaler hat geschrieben:
creed steiger hat geschrieben:da läuft Speicher aus


Unter welchem Linux hast Du das getestet?

Raspbian

Timm Thaler
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

Beitrag von Timm Thaler »

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.

creed steiger
Beiträge: 957
Registriert: Mo 11. Sep 2006, 22:56

Re: Programm braucht ständig mehr Speicher - Lazarus unter R

Beitrag von creed steiger »

Ich werds morgen vielleicht mal mit Qt probieren, das war mit GTK.
Nicht das es am Widgetset liegt.

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Programm braucht ständig mehr Speicher - Lazarus unter R

Beitrag von Michl »

creed steiger hat geschrieben:Nicht das es am Widgetset liegt.
Wird es wohl, da unter Windows kein Speicherzuwachs zu sehen ist.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Timm Thaler
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

Beitrag von Timm Thaler »

creed steiger hat geschrieben:Ich werds morgen vielleicht mal mit Qt probieren, das war mit GTK.


Ich würds auch gern testen, wie änderst Du das Widgetset in Lazarus unter Raspbian?

Antworten