Tkinter - Memory Leak With Canvas
Solution 1:
The underlying tk canvas doesn't reuse or recycle object identifiers. Whenever you create a new object, a new identifier is generated. The memory of these objects is never reclaimed.
Note: this is memory inside the embedded tcl interpreter, rather than memory managed by python.
The solution is to reconfigure old, no longer used elements rather than deleting them and creating new ones.
Solution 2:
Here's the code with no memory leak. The original source of the leak was me deleting the old line then creating a new one. This solution moves the first the line to the end then change's its attributes as necessary. I had a second 'leak' in my example code where I was picking a random color each time which lead to the number of colors used eating up a lot of memory. This code just prints green lines but the length will be random.
import tkinter
from tkinter import Tk, Frame, Canvas, ALL
import random
def RGB(r, g, b):
return '#{:02x}{:02x}{:02x}'.format(r, g, b)
class MainUI:
def __init__(self, master):
self.master = master
self.lineList = []
self.xPos = 0
self.maxLine = 122
self.responseIndex = 0
self.responseWidth = 100
self.responseTimeCanvas = Canvas(self.master, height=self.responseWidth)
self.responseTimeCanvas.pack()
self.UpdateResponseTimeGraph()
def UpdateResponseTimeGraph(self):
self.lineLength = random.randint(10,99)
if len(self.lineList) >= self.maxLine:
self.lineLength = random.randint(5,95)
self.responseTimeCanvas.coords(self.lineList[self.responseIndex % self.maxLine], self.xPos, self.responseWidth, self.xPos + 4, self.responseWidth-self.lineLength)
self.responseTimeCanvas.itemconfig(self.lineList[self.responseIndex % self.maxLine], fill=RGB(100, 255, 100))
else:
self.lineList.append(self.responseTimeCanvas.create_rectangle(self.xPos, self.responseWidth, self.xPos + 4, self.responseWidth-self.lineLength,
fill=RGB(100, 255, 100), outline=''))
self.xPos += 5 #will cause the next line to start 5 pixels later.
self.responseIndex += 1
self.responseTimeCanvas.config(scrollregion=self.responseTimeCanvas.bbox(ALL))
self.responseTimeCanvas.xview_moveto(1.0) #move to the end of the canvas which is scrollable.
self.responseTimeCanvas.after(10, self.UpdateResponseTimeGraph)
mw = Tk()
mainUI = MainUI(mw)
mw.mainloop()
Post a Comment for "Tkinter - Memory Leak With Canvas"