event processing & garbage collection in Tcl and Tk

Note: this page shall document facts about the circumstances where Tcl and Tk process garbage collection.

RJM asks if anybody can describe details about garbage collection process invocations. Currently, I assume that Tcl does automatic memory management when nothing is done. In conjunction with the Tk event loop: This would happen when the idle state is present/reached. I also assume that Tcl and Tk have their own collectors, since both subsystems have their own data structures (I mean, Tk has hidden window related data which can be accessed by Tcl via config subcommands etc.). Of course Tk objects may normally be destroyed explicitly, hence making automatic memory freeing unnecessary, but I experienced that e.g. coordinate lists of complex line objects may well be subject to automatic memory management.

Further, I believe that events (i.e. events that are hardware interrupts) may well delay or interrupt (or even cancel) any running garbage collection. A practical code example showing that animation speed in widgets may well depend on (timed) event sources in relationship with animations involving changes in data structures makes this assumption viable: event/response delay investigation.

DKF: Actually no. Tcl and Tk manage memory eagerly, releasing it as soon as the reference to it vanishes.

04aug04 jcw - Not sure where you're going with this, Rob. I'm assuming you are referring to the release of memory used in Tcl_Obj* instances. GC, in Tcl's world, is done with reference counts. When the count drops to zero, the instance is deleted. If that causes another refcount to drop to zero, that instance is deleted as well. And so on. The moment when this happens is strictly defined, i.e. right when a refcount drops to zero. This can come from variables/arrays being unset, going out of scope, or having their contents changed. In that last case, the old value may not be used anymore.

There is "garbage collection" in the sense that one cleanup can trigger more cleanups. That could in fact be a lengthy process, try for example:

  set a ""
  for {set i 0} {$i < 10000} {incr i} {
    set a [list $a $a]
  puts [time { unset a }]

The most likely places for such "unwinding cleanups" would be proc returns or explicit unsets, I think. But I can't quite see how events or idle time can affect any of this.

PS. The above code exposes a serious limitation in Tcl, btw (I used tclkit 8.4.6): when the above script is done with 100000 iterations, the unset crashes, presumably due to a stack overflow in the C-based unset logic. OUCH!

DKF: 8.5 seems to be much faster than 8.4 at cleaning this sort of thing up, and it ought to be protected against those sorts of stack crashes too. :^)

RJM: Thanks Donal and Jean-Claude for the clarifications. At least I know (now) that memory freeing in Tcl is done quite deterministically (contrary to "in irregular time intervals"). The actual problem as referenced to above seems to be restricted to Tk (mainloop) internals. Strictly related to the title of this page I'd say another title would fit better to the topics here. How about "event processing, priorities and running action interruption"?. Perhaps I'd split the page in two pages (in a couple or days or so).