Curbside Collection is a TCL answer to the problem answered by Garbage Collection in other systems. The idea behind Curbside Collection is that the developer is a better judge of what should and should not be automagically dumped by the system. For performance reasons, most applications need certain objects to always exist at a given name, and having to request the object be transparently created for each call gets to be expensive. Especially because we are using script to create the objects, not C code or Java bytecodes. Yes, one could design several mechanisms into the Garbage Collection system that would allow an object to side step it. But why? Curbside Collection uses a central mechanism that registers objects that are known by the developer to be temporary and fleeting. I call this mechanism "thanatos", after the Greek God of Death. The record keeping in Thanatos is simply two arrays. One stores the object handle and a clock seconds time stamp of when the object was last referenced. The other stores the object handle and a script to call to destroy the object. Objects interact with thantatos through several simple procedures: ::thanatos::alloc OBJECT DESTROYSCRIPT - Register an object and destroy procedure with thanatos ::thanatos::free OBJECT - De-Register and object ::thanatos::touch OBJECT - Mark that an object has been used In the background thanatos periodically runs a polling script. The script looks through the objects in its care. If an object has not been "touched" in a while, it is put on the curb. After the polling script, thanatos politely tells the object to die. Well actually it calls the destructor or the object systems' delete mechanism as appropriate. Polite objects will call ::thanatos::free in their destructor, but just in case thanatos will also free the object after the delete call. For the good of the order, here is the code from [SDW]'s [TAOHTTPD] system: ### # Odie object allocation and garbage collection mechanism # # All objects created are "allocated" through this # mechanism. It records when they were created and when they # were last accessed. # # Nodes record the nodes they depend upon, and container # objects are preserved accordingly. ### package provide tao-thanatos 0.1 namespace eval ::tao { variable object_pool variable kill_time 60 variable kiss_list if ![info exist kiss_list] { set kiss_list {} } array set object_pool {} proc alloc {object} { variable object_pool set object_pool($object) [clock seconds] } proc free {object} { ::tao::cache::clear $object variable object_pool variable kiss_list array unset object_pool $object ldelete kiss_list $object } proc touch object { variable object_pool if [info exists object_pool($object)] { set object_pool($object) [clock seconds] } } proc kiss object { variable kiss_list ladd kiss_list $kiss_list set ::tao(kiss_pending) 1 } ### # Is anyone in need of a good killing? ### proc knock {} { variable kiss_list if { [llength [get kiss_list]] > 0 } { return 1 } return 0 } proc cleanup {} { set ::tao(kiss_pending) 0 variable object_pool variable kill_time variable kiss_list ### # Start with a list of all objects ### set pool [array names object_pool] ### # Clean out any immortals the strayed off the reservation ### foreach item $pool { if [catch {set i [$item Immortal]}] { set i 1 } if $i { free $item } } set pool [array names object_pool] ### # Step 2 eliminate everything that # has been accessed in the last # n seconds ### set cutoff [expr [clock seconds] - $kill_time] foreach item $pool { if { [lsearch $kiss_list $item] < 0 } { if { $object_pool($item) > $cutoff } { ldelete pool $item } } } ### # Everything left, delete ### foreach item $pool { catch {::tao::delete $item} err free $item } } proc thanatos {} { variable event if [info exists event] {after cancel $event} set event [after 60000 ::tao::thanatos] puts "Running Cleanup" cleanup } } ### # Interface to the odie garbage collector ### ::tao::class ::thanatos::mortal { proc Immortal {} { return 0 } metaconstructor { ::tao::alloc $this } chain Regenerate {} { ::tao::kiss $this } destructor { ::tao::free $this } } ::tao::class ::thanatos::immortal { proc Immortal {} { return 1 } proc Regenerate {} { return {} } metaconstructor { ::tao::free $this } } ### # Startup Garbage Collector ### ::chronos JobCreate ::chronos::job::script \ -interval $::tao::kill_time -job_name "Garbage Collector" \ -script ::tao::cleanup