You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using tk.createcommand you get a memory leak when you don't explicitly call tk.deletecommand to remove this command.
See attached file: __del__ never get's called due to the memory leak and because of that calling tk.deletecommand inside __del__ has no effect. If you remove the tk.createcommand everything works fine.
There are two problems: one in your code and one in tkinter or Tcl.
The problem with your code is that it creates new Tcl interpreters in loop. Create a single Tcl interpreters and create commands in a loop. This will reduce the leak to constant amount.
The problem with either the tkinter module or the Tcl interpreter is that the reference to created commands should be released when delete the command explicitly (Tcl_DeleteCommand), or create a new command with the same name (Tcl_CreateCommand), or delete the Tcl interpreter (Tcl_DeleteInterp), but for unknown cause this doesn't happen in the last case.
Tkinter calls Tcl_DeleteInterp when a Tk object is garbage collected, and it registers a cleanup callback for each registered command, which according to the Tcl docs should be called upon Tcl_DeleteInterp[1]. So this must either be a bug in Tcl or something in the circumstances isn't giving it a chance to clean up the commands.
It's worth noting that Tk.destroy() calls Misc.destroy() which explicitly calls deletecommand for all registered commands. So calling .destroy() when done with a Tk instance, which is good practice in general, will also avoid this issue.
Considering the above, I'm not sure this is worth investigating and addressing...
A simple solution could be to add __del__ to Tk or Misc and have that also clean up any registered commands.
Activity
WKraus commentedon Apr 30, 2019
When using tk.createcommand you get a memory leak when you don't explicitly call tk.deletecommand to remove this command.
See attached file: __del__ never get's called due to the memory leak and because of that calling tk.deletecommand inside __del__ has no effect. If you remove the tk.createcommand everything works fine.
[-]createcommand memory leak[/-][+]tkinter tk.createcommand memory leak[/+]serhiy-storchaka commentedon May 2, 2019
There are two problems: one in your code and one in tkinter or Tcl.
The problem with your code is that it creates new Tcl interpreters in loop. Create a single Tcl interpreters and create commands in a loop. This will reduce the leak to constant amount.
The problem with either the tkinter module or the Tcl interpreter is that the reference to created commands should be released when delete the command explicitly (Tcl_DeleteCommand), or create a new command with the same name (Tcl_CreateCommand), or delete the Tcl interpreter (Tcl_DeleteInterp), but for unknown cause this doesn't happen in the last case.
taleinat commentedon Aug 5, 2019
Tkinter calls Tcl_DeleteInterp when a Tk object is garbage collected, and it registers a cleanup callback for each registered command, which according to the Tcl docs should be called upon Tcl_DeleteInterp[1]. So this must either be a bug in Tcl or something in the circumstances isn't giving it a chance to clean up the commands.
It's worth noting that Tk.destroy() calls Misc.destroy() which explicitly calls deletecommand for all registered commands. So calling .destroy() when done with a Tk instance, which is good practice in general, will also avoid this issue.
Considering the above, I'm not sure this is worth investigating and addressing...
A simple solution could be to add __del__ to Tk or Misc and have that also clean up any registered commands.
gh-80937: Fix memory leak in tkinter createcommand (GH-152294)
[3.13] gh-80937: Fix memory leak in tkinter createcommand (GH-152294) (…
[3.14] gh-80937: Fix memory leak in tkinter createcommand (GH-152294) (…
[3.15] gh-80937: Fix memory leak in tkinter createcommand (GH-152294) (…