Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Subroutine Memory Leak

by gopika77 (Initiate)
on Jul 31, 2006 at 04:28 UTC ( [id://564672] : perlquestion . print w/replies, xml ) Need Help??

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

i have a sub routine which is called for every 15 minutes using the repeat()..The problem is the memory leak..The variables which i use in the subroutine are allocated memory evry 15 minutes..The previous variable memory is not reused. Even undef the variable doesnot help.. sub auto { $var; and i do some code manipulations here.. return; } Perl Monks any solution to this problem? Thanks a million.. The sample working code is as below..Please Help
use Tk; $var=20; $mw = MainWindow->new(); $mw->geometry( "240x200" ); $mw->Label(-text=>"Subroutine Memory Leak")->pack; &startloop; MainLoop; sub startloop { $iid = $mw->repeat( 1500,\&autorefresh) ; return; } sub autorefresh { $var= $var + 20; $mw->Label(-text=>"$var",-font=>'arial 14 bold')->place(-x =>100,-y => +50,-anchor => 'nw'); return; } ...
Update: Added code snippet.I tried using Strict but it doesnot Help Much
use Tk; use strict; my $var=20; my $mw = MainWindow->new(); $mw->geometry( "240x200" ); $mw->Label(-text=>"Subroutine Memory Leak")->pack; &startloop; MainLoop; sub startloop { my $iid; $iid = $mw->repeat( 1500,\&autorefresh) ; return; } sub autorefresh { $var= $var + 20; $mw->Label(-text=>"$var",-font=>'arial 14 bold')->place(-x =>100,-y => +50,-anchor => 'nw'); return; }

Replies are listed 'Best First'.
Re: Subroutine Memory Leak
by ikegami (Patriarch) on Jul 31, 2006 at 05:11 UTC

    I think the problem is that you keep creating new Label objects. Since you don't destroy them, they just keep accumulating until you close the dialog. You should change the text of the existing label instead of creating a new Label every time autorefresh is called. I'm not familiar with Tk, so I can't help you with the syntax.

    By the way, it's polite to say "Update: Added code snippet." or something of the kind when you update a node. It avoids confusion when existing replies refer to the original node content.

      I need help in detail..pls let me know how to use it
        The following changes will help:
        my $var = "Subroutine Memory Leak"; $mw->Label( -textvariable => \$var )->pack; sub autorefresh { # $var = $var + 20; $var += 20; return; }

        Don't create a label each time in sub autorefresh. You create a new label each time the sub is executed, but the previous one is still there. You are placing a label over a label over a label over a label...

        --shmem

        update: tested. Memory stays dead on at 7456/5064 VIRT/RES on my system.

        _($_=" "x(1<<5)."?\n".q/)Oo.  G\        /
                                      /\_/(q    /
        ----------------------------  \__(m.====.(_("always off the crowd"))."
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
        i checked the code even just giving print to screen without TK the same memory leak
Re: Subroutine Memory Leak
by GrandFather (Saint) on Jul 31, 2006 at 09:05 UTC

    As suggested above creating a new widget every tim ethe sub is called is not optimum. Try the following code with LEAK set to 1 and to 0 to see the difference in behaviour:

    use warnings; use strict; use Tk; use constant LEAK => 1; my $var; my $handle; my $mw = MainWindow->new(); my $label = $mw->Label(-text=>"Subroutine Memory Leak")->pack; my $button = $mw->Button(-text=>"ClickMe", -command=>\&startloop)->pac +k; #&startloop; MainLoop; sub startloop { my $iid; $iid = $mw->repeat( 300,\&autorefresh) ; return; } sub autorefresh { $var++; if (LEAK) { $mw->Label(-text=>"$var",-font=>'arial 14 bold')->place(-x =>1 +00,-y =>50,-anchor => 'nw')->pack; } else { $label->configure (-text=>$var); } }

    DWIM is Perl's answer to Gödel
Re: Subroutine Memory Leak
by atcroft (Abbot) on Jul 31, 2006 at 05:56 UTC

    What does this do for you? Does it leak in this case?

    use Tk; use strict; my $var = 20; my $mw = MainWindow->new(); $mw->geometry("240x200"); my $leaking_label = $mw->Label( -textvariable => \$var, -font => q{arial 14 bold} )->place( -x => 100, -y => +50, -anchor => q{nw} ) ->pack; &startloop( \$var ); MainLoop; sub startloop { my ($v) = @_; my $iid; $iid = $mw->repeat( 1500, sub { autorefresh($v) } ); return; } sub autorefresh { my ($v) = @_; $$v += 20; }

    HTH.

      Thanks for your effort but sadly it Leaks, the Leak is the same no difference..Any other ideas
Re: Subroutine Memory Leak
by superfrink (Curate) on Jul 31, 2006 at 06:35 UTC
    It might be an old bug or a platform dependent bug (eg in a C library). Can you post some more details like the platform (operating system and maybe CPU type) you are running on, what version of perl and Tk.

    Also how do you know there is a memory leak? Are you watching the memory size in "top"? Possibly a library somewhere allocates memory over time and only frees it when the memory use gets too large.

    I really am guessing at where the problem is but it's hard to find memory problems when you can't see them for yourself. Or you can't reproduce them like I think I saw some discussion about in the chatterbox.
      i'm using windows 2000 with Active Perl5.8. 512MB RAM.. I'also tried it on Mandrake Linux 10.1 and the same behavior is observed. any clues?? The memory leak can be viewed through task manager and watch the perl.exe's memory to grow... On Linux just type ps aux and you can see the allocated memory to grow.
Re: Subroutine Memory Leak
by zentara (Archbishop) on Jul 31, 2006 at 13:03 UTC
    I echo the previous advice, that you are creating a new label each update, so reuse the label object. Using -textvariable instead of -text is also a good solution. This example does not leak (at least after a few hundred updates, you may find some very minor leakage after days of running, but it wouldn't be much). UPDATE: I made the example a bit clearer.
    #!/usr/bin/perl use warnings; use strict; use Tk; my $var = 20; my $mw = MainWindow->new(); $mw->geometry( "240x200" ); my $label = $mw->Label( -text=>"Subroutine Memory Leak", -font=>'arial 14 bold', )->pack; my $label1 = $mw->Label( -text=> $var, -font=>'arial 14 bold', )->pack; &startloop; MainLoop; sub startloop { my $iid = $mw->repeat( 150, \&autorefresh) ; return; } sub autorefresh { $var = $var + 20; $label1->configure( -text=> $var ); return; }

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: Subroutine Memory Leak
by Tanktalus (Canon) on Jul 31, 2006 at 04:39 UTC

    You're going to have to give a lot more information than that - I can't reproduce your problem with the code you've given, which is going to make it hard for most of us to guess what you're referring to. Please see:

    Thanks,

Re: Subroutine Memory Leak
by McDarren (Abbot) on Jul 31, 2006 at 04:36 UTC
    Although I won't pretend to be an expert on the internals of Perl, I do know that in general it does a pretty good job of handling memory allocation - and it's something that you usually don't have to worry about.

    And that's probably the most sensible answer that you're going to get for now, unless you take the time to post some code that demonstrates your problem.

    Cheers,
    Darren

Re: Subroutine Memory Leak
by Dervish (Friar) on Jul 31, 2006 at 06:29 UTC

    I have an ancient (and therefore, likely to be wrong in particulars) of repeatedly calling a 'memory available' function with a (C) program that simply did a lot of allocations and frees. The memory available kept dropping until some threshold, and then started oscillating.

    We took this to mean that more was being allocated to the process, and the free list (or equivalent) was not scavenged until it was needed. It may be relevant.
Re: Subroutine Memory Leak
by eXile (Priest) on Jul 31, 2006 at 04:49 UTC
    I agree with the previous comment that if you want people to look at your problem seriously, more code is seriously needed.

    Without code I can only mumble generalities like:

    • How have you determined you have a memory leak?
    • Are you using strict and warnings?