Grygonos has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I have the following code

sub guiStart { my ($client,$login) = @_; my $mw = MainWindow->new(-borderwidth=>30, -title=>"Duplicates: ".$$client); my %layout = ('frame' => [], 'label' => [], 'callback'=> []); #Construct labels $layout{'label'}->[0] = 'List Available Data'; $layout{'label'}->[1] = 'Remove Data'; $layout{'label'}->[2] = 'Add Data'; $layout{'label'}->[3] = 'Identify Duplicates'; $layout{'label'}->[4] = 'Change Client'; $layout{'label'}->[5] = 'Exit Application'; #Set callbacks $layout{'callback'}->[0] = [\&listData,$client,$login,$mw]; $layout{'callback'}->[1] = [\&removeData,$client,$login,$mw]; $layout{'callback'}->[2] = [\&addData,,$client,$login,$mw]; $layout{'callback'}->[3] = \&identifyDuplicates; $layout{'callback'}->[4] = \&changeClient; $layout{'callback'}->[5] = \&exitApp; for (0..5) { #Create the frames $layout{'frame'}->[$_] = $mw->Frame(); #Create the buttons $layout{'frame'}->[$_]->Button(-text =>$layout{'label'}->[$_ +], -width =>20, -command=>$layout{'callback'}-> +[$_])->pack(); $layout{'frame'}->[$_]->pack(); } MainLoop; return; }
I had asked for opinions on the gui setup in a previous SoPW node, but now I come with a different question. The call back that references \&removeData has a possible memory leak. Here is the code for removeData
sub removeData { my ($client,$login,$mw) = @_; my @tapes = getTapes($client,$login); #Create a DialogBox my $dlg = $mw->DialogBox(-title =>"Delete tape for: ".$$clien +t, -buttons =>['Delete','Cancel'], -borderwidth=>5); my $list = $dlg->Scrolled('Listbox', -scrollbars=>'oe os', -background=>'black', -foreground=>'white', -height =>12, -width =>12)->pack(); $list->insert('end',$_) for @tapes; + my $choice= $dlg->Show(); my $num = $list->get($list->curselection()); #If the user chose Delete if(lc($choice) eq 'delete') { #Drop the listbox $list->packForget(); #Reconfigure the dialog title $dlg->configure(-title =>'Delete Confirmation!'); #Reconfigure the dialog button text $dlg->Subwidget('B_Delete')->configure(-text=>'Yes'); $dlg->Subwidget('B_Cancel')->configure(-text=>'No'); $dlg->Label(-text=>"Tape:".$num." will be deleted. Are you su +re?")->pack(); if(lc($dlg->Show()) eq 'yes') { my $success = deleteTape($client,\$num,$login); } } return; }
If I open this dialog box from the callback, the memory usage goes up. If I close it and re-open it .. it continues to go up. I fail to see why this would happen. Am I missing something obvious? Are there good tools that can help me identify this on my own?

Thanks,

Grygonos

Replies are listed 'Best First'.
Re: Need Help Identifying Possible Tk Memory Leak
by eserte (Deacon) on Jul 12, 2004 at 16:17 UTC
    I think that the dialogbox is not removed from your system. Try either to explicitely destroy() the dialog box, or reuse the dialog box. The latter solution is also done with the standard dialog boxes like the file selection dialog.

      Explicitly calling destroy does help. I did that shortly after posting and it made a dramatic difference in the memory allocated each time the window was redrawn.

        Apropos of creating and deleting Tk windows, I wonder about the main program that calls your "guiStart" sub. Does this sub get called numerous times during the execution of the main script? Or is it rather the case that the main script does some stuff, calls this sub, does a few other things after the gui shuts down, then exits?

        If this gui comes up numerous times (for that matter, if the dialog box comes up numerous times), you might consider restructuring the app so that the windows/widgets are all created just once, then made to appear, disappear and reappear as needed, without destroying and recreating them.

        Creating and destroying widgets involves a lot of extra work; it might not be a problem now, but if you have a larger app with more widgets or more data being displayed in widgets, it can slow things down noticeably. Meanwhile, reconfiguring widgets to be visible or not visible, or changing the data that they display, is relatively fast.

Re: Need Help Identifying Possible Tk Memory Leak
by pg (Canon) on Jul 12, 2004 at 15:43 UTC

    Not trying to be picky, but memory leak has its own meaning.

    A piece of memory is said to be leaked, if there is no way the program can free it, as the handler to that piece of memory is lost because of mistakes.

    A piece of code can be coded in such a way, that it does not free memories that it no longer want. That is not memory leak, although that is quite careless, as long as you still have the handler. If you want, you still can free it, as you still have the handler, so the momery is not leaked.

    In general, pure Perl code does not cause memory leak.

Re: Need Help Identifying Possible Tk Memory Reuse Problem
by zentara (Cardinal) on Jul 13, 2004 at 14:24 UTC
    I second graff's advice.....create the dialogbox once, and withdraw it. When you need it, deiconify and raise it. Don't destroy it. You can also use the same dialogbox for different purposes, just reconfigure the text messages.

    Also in your create_gui sub, you are creating a new mainwindow, this will waste memory if called more than once. So create the $mainwindow once and withdraw it, and when you call the create_gui sub, $mw->deiconify; $mw->raise;


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