in reply to Re: Tk, HLists and memory leakage
in thread Tk, HLists and memory leakage

Your suggestion of separating the data storage from the widget is what I am doing already--unless you are suggesting that instead of pointing my widgets at values in an object instance that is dedicated to the widgets, I should be creating a separate hash. I don't see how that could help. My description of the issues must have been unclear.

I don't see the leakage when I use items of type text. The problem comes up with items of type 'window' or 'widget'. Memory seems to be reclaimed when I create and destroy text items.

As to using Data::Dumper, which values do I dump? I have already explicity destroyed my widgets, so I can't dump them. Dumping the MainWindow shows me nothing useful, same with the HList widget. What should I be dumping? What I'd really like to see is a memory map with each stored value and a set of reference counts for each.

Keeping items around and then configuring is fine if you have a static, well defined number of items you want to display. In my case, a rule may have one or 100 clauses. Creating and managing a pool of identical HList entries seems to be a hassle. Add to this the fact that I need to be able to change which widget is displayed in a given item, based on the values selected in other widgets (eg Field_1 has a list of legal values, but Field_2 can be any integer, so I use a menu and an entry, respectively, to handle input). Should I then pre-create entries with each possible set of widgets to meet my needs?

I could reduce the size of a precaching implementation by allocating a bank of each type of widget: HList items, Optionmenus, Entries, and Checkbuttons. Then I would need to track which ones were active, and which ones weren't, and probably handle making more as needed. Then available widgets could be assinged to available items in available entries. If I have to do all that, what benefit does the HList really offer over rolling my own similar functionality using a Frame and grid()? I chose the HList widget because it looked like should handle many of these issues for me. I am beginning to this this was a mistake.


TGI says moo

Replies are listed 'Best First'.
Re^3: Tk, HLists and memory leakage
by zentara (Cardinal) on Oct 21, 2005 at 10:09 UTC
    First, it will always be unclear to me what you are doing, because I'm not writing your app, and my head just isn't into what you are doing. All I can do is relate my similar experiences with HLists and mem leaks.

    As far as what widgets or hashes to dump, it is kind of an "art" to figure out where and what to dump. Try linux memory leak monitor and carefully watch what happens on each click of your app. You should be able to deduce which subs are being called when you see memory jumps, then dump all hashes involved. You can also use Devel::Size to get an idea of the size of the variables.

    As far as dealing with 1 or 100 clauses, and keeping a static number of widgets; you can do it. Just keep track of each widget-set you create for each clause, and store it all in a hash. If you don't need it, don't destroy it, just unpack it, and it will be there for future re-use. I know it sounds like a hassle to track and store all created widgets, unpacking, reconfiguring and repacking them as needed, but that is what you will have to do if you want to manage your memory and keep it from the constant upward increase.

    And of course, like you said, maybe the HList isn't the right widget for you, if your entries don't all use the same widgets. Maybe you could devise a few different Hlist's, each configured to display a different set of widgets, and call that HList model depending on your display needs. Maybe Tk::TableMatrix would better suit your needs?


    I'm not really a human, but I play one on earth. flash japh

      I am sorry if I sounded upset with you in my replies. I'm frustrated, and that probably came out in my tone. I didn't intend to be rude, especially not to someone who is trying to help. If I was impolite, or rude, or wrote inappropriately, I am truly sorry. It was not my intent to be rude and I hope you will accept my apology.

      Sadly, I am forced to develop on and for Windows, so I can't use the memory leak monitor. Platform issues notwithdstanding, it looks like it would be handy. I might be able to find a way to tweak it for windows. If I do, I'll post a reply to that node.

      Part of the problem is that I need to have a lot of dynamism in which widgets are displayed.

      To try to better explain what I'm doing, I'll break it down into smaller pieces--it may help to refer to the ASCII art in my OP. I need to display a list of clauses and allow the user to edit them. The interface is much like the one used by thunderbird to create mail filters. Each clause consists of a field name, an operator, and a value. Different fields have different lists of legal operators. Different fields also have different rules about what values are acceptable. For example, we have several temperature fields which have any number for their values; I use an entry for value entry. We also have a Wet/Dry field that can be only "Wet or Trace" or "Dry"; I use an option menu. If the user changes the field from TEMP to WD, then the value widget must be changed from an Entry to an Optionmenu and the operator Optionmenu must be changed to display the correct list or operations (you can't very well check to see if something is "less than or equal to" Wet). It's also worth noting that I may be working with any number of clauses, and I need to able to add or delete them as needed.

      I hade hoped to handle all this dynamism by creating and destroying the involved widgets and HList entries as needed. It looks like I can't do anything to cleanly expungethe widgets and entries though--even if I explicitly destroy my widgets, destroy my objects and delete my entries.

      So, to implement a cached-entry approach to my problem, I'll need to create a set of HList items that have the different possible widgets. When the user changes the field value, I will need to decide if I need to hide the current Hlist entry, uncouple it from my Clause object and configure an HList entry with the correct widget set to display the clause. Is that correct?

      I'll take a look at the TableMatrix widget. Thank you for the suggestions.


      TGI says moo

        No problem. I didn't get offended at all by your frustration. I remember the first time I got bit by HList's(and Tk's) memory gain problem. I spent about 2 weeks on something, figuring It was all ready to go, then I started watching the memory. Oh, the feeling in the pit of my stomach as I realized that 2 weeks was just ripped away from me. Thats why now, I check for memory gains with MeM, at every step in the development, to catch the problems before they get buried too deep in more code.

        As a general rule however, whenever you choose to use objects in a create-destroy cycle, you will get memory gains. Alot has been written on it in nodes here, and basically it has something to do with the "ref count" of the widgets. That means that an object is never truly destroyed as long as there is at least 1 ref to it somewhere. Now the problem with HList (and Tk) is that they keep hard to find refs buried deep in their code. So it's almost impossible to get the ref count to go to zero, once you use an object as part of a widget. HList in particular, seems to keep an hidden internal counter of it's children. So say if you create 10 entries, they will be 0-10 on the internal counter. If you delete those 10, and create 10 more, the internal counter is 11-20. Refs to objects can hide in there.

        So the safest procedure, is always design your programs to reuse all objects, never use the create-destroy cycle unless it's just a small short-lived program.


        I'm not really a human, but I play one on earth. flash japh