[CMcC] 20050301 - [jyl] was trying to track down what seemed to be a leak in a tcl program, which reminded me of a component of [tclhttpd] which tries to measure the size of variables and procs in an interpreter. I've packaged that up here, may it be of use. namespace eval tclsize {} # DataSize -- # # return the data size for the interpreter or for a particular namespace. # # Arguments: # ns (optional) if given, show the data size for this namespace # # Results: # Returns {size namecount varcount} proc tclsize::DataSize {{ns "::"} {interp ""}} { set ng 0 set nv 0 set size 0 foreach g [interp eval $interp info vars ${ns}::*] { incr ng if {[interp eval $interp array exists $g]} { foreach {name value} [interp eval $interp array get $g] { incr size [string length $name] incr size [string length $value] incr nv } } elseif {[interp eval $interp info exists $g]} { # info vars returns declared but undefined namespace vars incr size [string length $g] incr size [string length [interp eval $interp set $g]] } incr nv } foreach child [namespace children $ns] { foreach {csize cnv cng} [DataSize $child $interp] break incr size $csize incr nv $cnv incr ng $cng } return [list $size $nv $ng] } # CodeSize -- # # return the code size for the interpreter or for a particular namespace. # # Arguments: # ns (optional) if given, show the code size for this namespace # # Results: # Returns {size proc_count} proc tclsize::CodeSize {{ns ::} {interp ""}} { set np 0 set size 0 foreach g [interp eval $interp info procs ${ns}::*] { incr np incr size [string length $g] incr size [string length [interp eval $interp info args $g]] incr size [string length [interp eval $interp info body $g]] } foreach child [interp eval $interp namespace children $ns] { foreach {csize cnp} [CodeSize $child $interp] break incr size $csize incr np $cnp } return [list $size $np] } # InterpSize -- # # return the data and code size for an interpreter # # Arguments: # ns (optional) if given, show the data size for this namespace # # Results: # Returns {total datasize namecount varcount codesize proccount} proc tclsize::InterpSize {{interp ""} {recurse 1}} { foreach {data names vars} [DataSize] break foreach {code procs} [CodeSize] break if {$recurse} { foreach child [interp slaves $interp] { foreach {cdata cnames cvars} [DataSize $child] break incr data $cdata incr names $cnames incr cvars $cvars foreach {ccode cprocs} [CodeSize $child] break incr code $ccode incr procs $cprocs } } return [list [expr {$data + $code}] $data $names $vars $code $procs] } if {[info script] eq $argv0} { foreach {total data names vars code procs} [tclsize::InterpSize] break puts [subst { Total accounted: $total bytes. Data size: $data bytes in $vars variables ($names names.) Code size: $code bytes in $procs procs. }] }