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
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
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
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 ...
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.
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...