Tk Source Code

View Ticket
Login
Ticket UUID: 1173484
Title: Memory leak
Type: Bug Version: obsolete: 8.4.9
Submitter: nobody Created on: 2005-03-30 17:33:57
Subsystem: 99. Other Assigned To: hobbs
Priority: 5 Medium Severity:
Status: Closed Last Modified: 2005-04-08 02:33:29
Resolution: Invalid Closed By: hobbs
    Closed on: 2005-04-07 19:33:29
Description:
Test code:

while {1} {
frame .f
destroy .f
}

On large and long running projects memory usage
increases significantly over time.

If it is any help a valgrind log has been attached that
shows what it thinks maybe memory issues.
User Comments: hobbs added on 2005-04-08 02:33:29:
Logged In: YES 
user_id=72656

I'm going to call this closed, as we've wandered into the
itk realm.  However, my strong recommendation in your case
would be to avoid itk if you are having these memory issues.
 There are other, more modern solutions that provide the
same level of functionality.  Consider bwidgets, tile for
more widgets and snit or xotcl as OO systems.

s_a_white added on 2005-04-07 15:28:38:
Logged In: YES 
user_id=59929

Am actually trying to test incr tcl/tk.  Our layout is
approx this:

-A custom incremental tiler object which provides
functionality like grid and various other things.

-Internally we house child windows which again are custom
incremental widgets, most screens have no more than for of
these in the tiler.

-The chdwin has an title bar area (using tcl widgets) and a
contents area (frame).

-In each contents there can be anything.  The screen we are
testing with has about 60 incremental custom widgets, about
20 tcl labels/frames split over two visible pages, which we
grid as appropriate in the contents area.

Since this is an embededded computer with limited memory, no
mouse, etc, limited keyboard we bring up a menu with various
different type of displayable screens.  On selecting one we
remove the tiler object, before creating the new layout.

On tests just deleting the the tiler object and rebuilding
the same screen loses us between 5 to 10 MB of memory. 
After about 10 to 20 or so such changes swap kicks in the
the performance of the application plummits to being unusable.

We have tested using simplier widgets, not wrapping widgets
with itk_component (that makes a huge difference) using
delete object instead of destroy (some difference).  However
delete object only works in test scripts and seems to suffer
the same problems as destroy when used in an event.

We also are using namespaces and things like #auto on class
objects that will no doubt have similar issues (does #auto
suffer this uid problem to I wonder)?

Anyway I just went back to basics, what dosen't leak, and am
starting to make more complicated examples until it does.  I
found itk to generate an itk-delete-$w binding on destroy
but it still exists after object deletion.  However issues
like that are only detected using random names.

hobbs added on 2005-04-07 06:06:33:
Logged In: YES 
user_id=72656

Joe is correct about Tk_Uids, and eventually we'd like to
switch all to Tcl_Objs.  However, that just reaffirms that
the .t[clock clicks] is a bad way to test for mem leaks,
because the mem creep is expected.  Was there some other
aspect you wanted to test?  As a strict Tk mem leak query,
there doesn't seem to be a problem.

s_a_white added on 2005-04-07 05:28:44:
Logged In: YES 
user_id=59929

Any chance this can be re-opened, I don't seem to be able to
do it myself (think that is because my original post was
anonymous).

Am actually trying to find issues with incrtk.  Have been
using random names for testing as found it dosen't always
clear up properly after itself, some of which is hidden when
using the same name.

Anyway in hunting through the incrtk C code I got to a point
where I was unable to eliminate a leak.  This was tracked
back to tcl:

while {1} {
    set t .t[clock clicks]
    frame $t
    update
    destroy $t
}

Am just trying to build on something stable so can find the
more serious problems in incrtk, believed to be related to
itk_component use.

Joe has kindly already provided the reason for the memory creep:

A Tk_Uid is a special cache of strings, such that each
distinct string is stored exactly once.  Tk uses them for
widget names, text and canvas tag names, widget classes,
and a few others.  This is normally a win -- for example,
no matter how many Frame widgets you create, the class name
"Frame" is only stored once -- but it will cause a leak for
applications that use an arbitrarily large number of distinct
names (as the above snippet does).

s_a_white added on 2005-04-01 17:39:57:
Logged In: YES 
user_id=59929

Yes an update in the sequence does seem to sort the problem.
 I've been trying to hunt down memory leaks in our code so
have been creating/destroying various things in to see what
happens, hence came across this.

I'll add in an update for the testing.

s_a_white added on 2005-04-01 17:28:49:
Logged In: YES 
user_id=59929

Update for information:

-Rebuilt with -DPURIFY but no difference.

-valgrind information appears to be the same if you just
start wish and do destroy .

-Has been tested only on Xfree (not sure of version, or
graphics card) supplied with Redhat 9.0 and Mandrake 10.1
using xorg 6.7 on varying video setups (generally using
default selected driver, except on the nvidia machine).

As a further test (if this is possible) I busy looped in C
code the TKCreateMainWindow with Tk_DestroyWindow in the
hope that it removes various resource (de)allocations.  If
such a thing is a valid test then it also showed up the same
problem.

If this is a X related issue will it be followed up, i.e.
passing more specific details onto the relevent people?

jenglish added on 2005-04-01 07:40:28:
Logged In: YES 
user_id=68433

Followup: [while {1} { destroy [frame .f] } does cause the
VM size of the process to grow without bound.  However,
adding a call to [update] in the loop the VM size reaches a
steady state and remains constant.

I don't have a good explanation for why this would happen,
but it would not appear to be a leak, not even a transient one.

jenglish added on 2005-04-01 07:23:46:
Logged In: YES 
user_id=68433

I can replicate what looks like a leak in the wish process.

Running the following under valgrind --leak-check=yes
--show-reachable=yes:

for {set i 0} {$i < 3000} {incr i} { destroy [frame .f] }
destroy .

then changing 3000 to 4000 and running it again yields
identical valgrind logs (the only difference is the malloc
and free counts increase, both by an equal amount).

hobbs added on 2005-04-01 06:53:48:
Logged In: YES 
user_id=72656

I cannot repeat this on Linux or Windows off
core-8-4-branch.  A lot of the valgrind stuff is pointing at
X - possibly related to the X mem leak with cursors on some
X servers.  Otherwise you have to compile Tcl with -DPURIFY
to properly avoid a lot of the mem leaks that it pointed to
for Tcl (Tcl does it's own heap obj mgmt for speed).

nobody added on 2005-03-31 00:33:57:

File Added - 127799: info

Attachments: