Raspbery Pi 4 mit Python RAM zu schnell voll

Gast #7062637
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
Angehängte Dateien:
Gast #7063414
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
Gast #7063613
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.
#7063841
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 ...
Gast #7064293
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren