is there any way to clear matplotlib memory usage from a tkinter application, the following code is taken from Embedding in Tk, i just put it in a loop to make the memory leak more clear.
import tkinter
import matplotlib
print(matplotlib._version.version)
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
import gc
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
import psutil
import os, psutil
process = psutil.Process(os.getpid())
import numpy as np
import time
root = tkinter.Tk()
frame = tkinter.Frame(root)
root.wm_title("Embedding in Tk")
import matplotlib.pyplot as plt
def my_func():
global root,frame
fig = Figure(figsize=(5, 4), dpi=100)
t = np.arange(0, 3, .01)
ax = fig.add_subplot()
line = ax.plot(t, 2 * np.sin(2 * np.pi * t))
ax.set_xlabel("time [s]")
ax.set_ylabel("f(t)")
canvas = FigureCanvasTkAgg(fig, master=frame) # A tk.DrawingArea.
canvas.draw()
# pack_toolbar=False will make it easier to use a layout manager later on.
toolbar = NavigationToolbar2Tk(canvas, frame, pack_toolbar=False)
toolbar.update()
toolbar.pack(side=tkinter.BOTTOM, fill=tkinter.X)
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=True)
time.sleep(0.1)
# everything i tried to clear memory
ax = fig.axes[0]
ax.clear()
canvas.get_tk_widget().pack_forget()
toolbar.pack_forget()
canvas.figure.clear()
canvas.figure.clf()
canvas.get_tk_widget().destroy()
toolbar.destroy()
mem = process.memory_info().rss/2**20
print(mem) # in bytes
if mem > 1000:
root.destroy()
frame.destroy()
frame = tkinter.Frame(root)
root.after(10,my_func)
gc.collect()
if __name__ == "__main__":
root.after(1000,my_func)
root.mainloop()
it just keeps eating memory up to 1000 MBs,
i tried everything to remove this memory leak without hope, i tried the answer here, but it also didn't work How to clear memory completely of all matplotlib plots.
just updating the figure instead of creating a new figure on each loop iteration would "avoid" some of the memory leak, but it doesn't "fix it", how do i reclaim this memory ?
this issue seems related https://github.com/matplotlib/matplotlib/issues/20490 but i am using version 3.6.2
which should have it fixed, i can duplicate it on almost all python versions on windows, (but the code in the issue doesn't produce this problem)
tracemalloc only shows around 1 MB was allocated on python side, so the rest of the leak is on C side ... something isn't getting cleaned up.
Edit: this also seems related Tkinter - memory leak with canvas, but the canvases are correctly reclaimed, so it's not a bug in the canvases or tk.
Edit2: the renderer on the C side is not getting freed ... althought there seems to be no reference to it.