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

Garbage collection of 'my' variables

by mikeB (Friar)
on Aug 28, 2001 at 20:07 UTC ( #108482=perlquestion: print w/replies, xml ) Need Help??
mikeB has asked for the wisdom of the Perl Monks concerning the following question:

The sub below does not seem to be releasing the memory allocated to the $data and @pixels variables. I'm willing to accept that the first may be an issue with the Tk::Photo module. Why wouldn't the memory from @pixels be released?

The sub is called repeatedly, passing a Tk::Image. It works as expected other than the memory issue. The memory allocation is being tracked via WinNT's Task Manager and the debugging print statements.

sub averageColor { my $image = shift; my @average = (0,0,0); my $x; my $y; my @rgb; print "load data..."; my $data = $image->data(-from => (0,0,$image->width()-1, $image->h +eight()-1)); print "split..."; my @pixels = split(/ /,$data); print "avg..."; foreach (@pixels) { $average[0] += substr($_,1,2); $average[1] += substr($_,3,2); $average[2] += substr($_,5,2); } print "div..."; for $x (0 .. 2) { $average[$x] = int($average[$x] / ($image->width * $image->hei +ght)); } print "done\n"; @average; }

Replies are listed 'Best First'.
Re: Garbage collection of 'my' variables
by perrin (Chancellor) on Aug 28, 2001 at 20:49 UTC
    Memory from lexicals does not get released unless you explicitly undef them (or set to empty list with an array like this). See this thread for more.

      I've been afraid that this would become a bad meme and it appears to be happening (unless you are just replying to the subject line and not to the question actually posed in the article -- though the wording could be clearer, I admit).

      The fact that memory used directly by a lexical is not freed when the lexical goes out of scope is not much of an issue here for at least a couple of reasons.

      The primary reason is that the memory will get reused when you come back into the subroutine (and this is the reason that the memory wasn't freed -- Perl selecting "use more memory" at every design trade-off, this time over the alternative of "spend CPU time to free memory that you may later just need to reallocate"). So this would not explain the constantly increasing consumption of virtual memory (which is what the original question is about -- though you'd have to read it very carefully to figure that out, I think).

      The other item to note is that most of the memory consumed by @pixels is freed! When the @pixels array goes out of scope, each of the elements in @pixels is freed (since there are no other references to them), but the memory used by @pixels itself is not freed. This memory is roughly propotional to the maximum number of elements ever stored in @pixels.

      Anyway, I say that this is becoming a "bad meme" because I am increasingly hearing people spouting off "lexicals aren't freed" w/o including all of the "however"s that should go along with such a statement. I think that most of the time, the "however"s are more important. That is, most of the time, the fact that the memory used directly by the lexical is not freed doesn't matter much.

      It is only when you store a really large string directly into a lexical that this matters much at all. And even then, it is a one-time hit (per lexical) and so won't cause memory to grow and grow w/o bound (like several other things will).

      Back to the original problem, I'd probably use something more like:

      while( $data =~ /(\S+)/g ) { $average[0] += hex substr( $1, 1, 2 ); $average[1] += hex substr( $1, 3, 2 ); $average[2] += hex substr( $1, 5, 2 ); }
      in this case.

      Update: BTW, your suggestion to set the array to an empty list would do nothing. Setting an array to an empty list frees the elements (which will already happen) and doesn't free the memory for the array itself (which is also what will already happen). You can undef the array (undef @pixels;) to free the memory that it uses directly, but this is rarely a good idea (or else Perl would be doing that by default).

              - tye (but my friends call me "Tye")
        Agreed, memory consumption in this program should not grow over time unless the data used in the lexicals is larger on a later run. I thought he was asking why the memory used by his sub wasn't being released when the sub has finished. I didn't see any mention of it growing over time.

        I guess it's a tricky distinction to get across simply. Sorry for any confusion this may have caused people.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://108482]
Approved by root
[Corion]: Congratulations Lady_Aleena ;)
[Lady_Aleena]: Thanks Corion.
[Lady_Aleena]: This is one of my oldest accounts on the web. 8)

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (2)
As of 2017-04-26 07:36 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (469 votes). Check out past polls.