Forum: PC-Programmierung Raspbery Pi 4 mit Python RAM zu schnell voll


von frediDerFuchs (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe ein kleines Problemechen mit der Arbeitspeicher bzw. mit dem 
Pythoncode welcher dann scheinbar sehr schenll den RAM voll macht.
Habe einen RPi 4 mit 4 GB RAM und Raspberry Pi OS with desktop.

Das Projekt ist eigentlich ganz einfach, ein RPi 4 ist der access point 
(AP) für eine vielzahl an Sensorknoten, dieser speichert die enpfangenen 
Daten in eine Datei, es wird jede 5 Sek. aktualisiert und ein Diagram 
aus den Daten erstellt.

Nun habe ich das Problem dass jedesmal wenn ich der Code in den Zeilen 
288 bis 353 ausführe, schon nach nur wenigen Aktualisierungen bis zu 5MB 
RAM belegt wird bis es voll ist, sprich nach wenigen Stunden ist das 
System dann nicht mehr arbeitsfähig.
Kommentiere ich diesen Bereich aus, dann passiert nichts, der RAM bleibt 
wie er am anfang war und erhöht sich nicht mehr. Auch wenn ich keine 
empfangenen Daten in die Datei speichere erhöht sich der RAM sobald die 
Daten im Diagramm angezeigt werden, die Gleichen.

Kann mir jemand sagen woran es liegen könnte, habe ich da irgendwo eine 
immer wiederkehrende Neuerzeugung eies Objektes übersehen oder 
ähnliches?

Der Inhalt der Datei auf die zugegriffen wird sieht so aus, mit Tab 
getrennt, wenn es eine Rolle spielt:

2022/05/08  15:06:49  128  713.46  24.23  27.28  1023.51

Bin für jeden Tip sehr dankbar.

Wenn ich was vergessen habe seht es mir nach, einfach fragen ich werde 
es dann nachreichen

von Sascha W. (sascha-w)


Lesenswert?

Da wird wohl irgendwas nicht freigegeben.
Ich würde mal die Updatefunktion
self.updateDiagramm(self.fig, selectItem)
auskommentieren um zu schauen ob das Problem beim erstellen der Daten 
oder in der Erzeugung der Grafik im Canvas liegt.

Sascha

von WS (Gast)


Lesenswert?


von frediDerFuchs (Gast)


Lesenswert?

Sascha W. schrieb:
> Da wird wohl irgendwas nicht freigegeben.
> Ich würde mal die Updatefunktion
> self.updateDiagramm(self.fig, selectItem)
> auskommentieren um zu schauen ob das Problem beim erstellen der Daten
> oder in der Erzeugung der Grafik im Canvas liegt.
>
> Sascha

Vielen Dank für den Tipp,

scheinbar liegt es an dieser Funktion, sobald ich es auskommentiere 
passiert nichts mehr mit dem RAM, aber dann kommt auch keine Grafik, ich 
habe noch die manuelle Freigabe, mit del und gc.collect, eingefügt aber 
es löst das Problem nicht

    def updateDiagramm(self, fig):
        canvas = FigureCanvasTkAgg(self.fig, master=self.window)
        canvas._tkcanvas.grid(row=0, column=2, rowspan=14, sticky=W + E 
+ N + S, padx=3, pady=3)
        del canvas, self.fig
        gc.collect()

WS schrieb:
> Hinweis:
> 
https://stackoverflow.com/questions/58508585/increased-memory-consumed-by-matplotlib-when-plotting-in-a-loop

Ich werde mit den Link nochmal genauer anschauen, auf die Schnelle hatte 
ich kein Erfolg, ich habe das Problem jedoch mehr verstanden

Was kann man da noch machen bzw. freigeben?

Grüße

von Karl (Gast)


Lesenswert?

Soweit ich es sehe legst du jedes mal einen neuen Plot an:
1
self.fig = Figure(figsize=(5.3, 4), facecolor="white")
2
self.axis = self.fig.add_subplot(111)

Du möchtest aber nur die Linien neu zeichnen.

von Sebastian W. (wangnick)


Lesenswert?

frediDerFuchs schrieb:
> def updateDiagramm(self, fig):
>         canvas = FigureCanvasTkAgg(self.fig, master=self.window)
>         canvas._tkcanvas.grid(row=0, column=2, rowspan=14, sticky=W + E
> + N + S, padx=3, pady=3)
>         del canvas, self.fig
>         gc.collect()

Das reicht nicht aus um die matplotlib FigureCanvasTkAgg und die darin 
enthaltene _tkcanvas aus dem GUI zu entfernen. Es fehlt:
1
        canvas.destroy()

Du musst dir also die FigureCanvasTkAgg in self merken, und die alte mit 
.destroy() zerstören bevor du eine neue erzeugst und dir wieder merkst.

LG, Sebastian

PS: Mein Tk-Python ist etwas rostig, also YMMV ...

: Bearbeitet durch User
von Mehr GHz! (Gast)


Lesenswert?

Mit Frickelkram wirst du nie eine stable (= 10 Jahre Laufzeit
ohne Reboot) zu stande bringen.

von MaWin (Gast)


Lesenswert?

frediDerFuchs schrieb:
> manuelle Freigabe, mit del

del gibt keinen Speicher frei.
Es löscht lediglich den Namen.

Wenn es dann irgendwann kein Namen mehr für das Objekt gibt, dann wird 
es automatisch freigegeben.
Speicherlecks in Python sind eigentlich immer irgendwelche 
selbstreferenzierenden Strukturen. Solche zirkuläre Strukturen müssen 
manuell aufgebrochen werden.

Oder ein kaputtes C-Modul gibt Referenzen nicht richtig frei.

von Ein T. (ein_typ)


Lesenswert?

frediDerFuchs schrieb:
> Das Projekt ist eigentlich ganz einfach,

Schon die ausgeuferten Importe weisen darauf hin, daß das Projekt alles 
andere als einfach ist... zumal die Importe auch einiges beinhalten, was 
nun wirklich nicht zu einander paßt. Flask UND Tkinter, Tkinter UND 
Threading? Äh...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.