Updated 2018-05-20 17:56:35 by pooryorick

Why does Tcl leak memory?. It doesn't, with rare exceptions. TCT takes memory leaks very seriously. Few ever escape into a release, and few known ones survive long.

See Also  edit

memory
memory leak finding with memory trace
Why Do Programs Take Up So Much Memory ?
How to debug memory faults in Tcl and extensions
Memory introspection
Measuring memory usage
Memory Footprint Comparisons
Memory costs with Tcl
Memory used by tcl script, comp.lang.tcl, 2004-05-07
tclguy mentions Tcl's own memory allocator with its high-water marking.
Memory problem, comp.lang.tcl, 2003-10-14
tclguy mentions the Tcl_Obj pool, and that memory is held at the high water mark if you use a threaded build, which has its own memory allocator, or you specifically use the internal Tcl allocator.

Description  edit

There are at least an order of magnitude more perceived memory leaks. These result mainly from causes such as:

  • Mis-measured memory use.
  • Userland, or application-level, memory leaks.
  • System or underlying language libraries (like libc for the C * implementation of Tcl).
  • photo images created and not deleted, though never ever used * (arguably, this is a kind of userland memory leak).
  • Files have been opened but not closed - check file channels to see * them.

An example of an application-level memory leak is a failure to clean up such Tcl global variables as the token http::getUrl return.

Discussion  edit

LV: Is there a list of known memory leaks in either Tcl 8.4 or 8.5? We regularly see people here on the wiki or in comp.lang.tcl which are trying to track down memory leaks. Sometimes, the code is only a dozen lines of code, and so doesn't look like a coding leak...

EKB 20016-03-12: I have two memory-related questions:

  • Are compiled regular expressions released from memory? If they are, at what point does this happen? (And if not, can I call them up again without recompiling them?)

Lars H: As I recall it, there are at least two places where compiled regular expressions are stored. One is in the Tcl_Obj, and that goes away when the Tcl_Obj does or changes representation. The other is that the regular expression compiler maintains a cache of recently compiled regexps and their compiled form; I think this cache is limited to 20-or-so elements. I don't know if there are any others. EKB - Thanks!

  • Are bindings for a window released from memory when the window is destroyed?

I ask because I'm debugging a tough memory leak, and these are two prime culprits.

If this is the wrong place to put such questions, please send me to the right place. Thanks!

comp.lang.tcl might be a better place to ask.

DKF: Bindings are indeed released, but there are things in Tk which are not. In particular, window names (not the full names, but just the last component of each name) and canvas and text tags (strictly, anything that is a Tk_Uid) are not deleted ever in Tk 8.4. In 8.5, they are per-thread resources, which will mean that you have to dispose with the thread to get rid of them. (You could argue that this is a highly sucky situation, and I wouldn't disagree.) See Fixing Tk_Uid leaks.

A workaround for this is to reuse the names of these sorts of things as much as you can. Like that, you just have high-water-mark effects instead of total-cumulative effects, meaning that virtually all programs will settle out at a certain level of usage instead of gobbling up ever more.

EKB: Thanks very much. This gives me a lot of promising things to try.

I am working on a leak I found in tk 8.4.6 (oldie but goodie; needed for my production site). Here is the data from valgrind:
==3514== 2,016 bytes in 12 blocks are definitely lost in loss record 140 of 187
==3514==    at 0x40046C1: malloc (vg_replace_malloc.c:149)
==3514==    by 0xBFD343: XcursorCursorsCreate (in /usr/X11R6/lib/libXcursor.so.1.0.2)
==3514==    by 0xBFE833: XcursorImagesLoadCursors (in /usr/X11R6/lib/libXcursor.so.1.0.2)
==3514==    by 0xBFE910: XcursorImagesLoadCursor (in /usr/X11R6/lib/libXcursor.so.1.0.2)
==3514==    by 0xC016DE: XcursorTryShapeCursor (in /usr/X11R6/lib/libXcursor.so.1.0.2)
==3514==    by 0x86AD76: XCreateGlyphCursor (in /usr/X11R6/lib/libX11.so.6.2)
==3514==    by 0x8826B73: TkGetCursorByName (tkUnixCursor.c:225)
==3514==    by 0x8814D79: TkcGetCursor (tkCursor.c:261)
==3514==    by 0x8814C37: Tk_AllocCursorFromObj (tkCursor.c:153)
==3514==    by 0x88124C1: DoObjConfig (tkConfig.c:873)
==3514==    by 0x8812C11: Tk_SetOptions (tkConfig.c:1358)
==3514==    by 0x87A2267: ConfigureFrame (tkFrame.c:949)

Best I can tell, the problem is that when the configuration options are freed, it's not calling Tk_FreeCursorFromObj().

A perusal of the latest tk release didn't yield any insights. Anybody know about this one?