http://qs321.pair.com?node_id=105133


in reply to (tye)Re: Tracking Memory Leaks
in thread Tracking Memory Leaks

Just to be clear, the memory used directly by the lexical is not freed but if, for example, the lexical contains the last reference to something, then that something will be destroyed and its memory freed when the lexical's scope is left (or when the last reference to the lexical is destroyed). So this is mostly a problem when dealing with long strings rather than objects.

No, I don't think that's correct. The memory will not be freed, if by freed you mean "available for use by other variables in my program". It will be re-used if you use that lexical again. See this post from Doug MacEachern for more info on this.

I'm not sure the closures thing I was talking about is really a bug; it's just a side-effect of nested subs and closures. If you do this, it will leak like crazy:

my $foo; sub bar { sub baz { $foo++; } }

It's creating a new private copy of $foo for baz() every time. Using Error.pm can sometimes lead people to do this without realizing it, when they use nested try/catch blocks.

Replies are listed 'Best First'.
(tye)Re2: Tracking Memory Leaks
by tye (Sage) on Aug 15, 2001 at 23:02 UTC

    Please reread what I wrote. I agreed that the memory used directly by the lexical will not be freed. But I wanted to clarify that in many cases this doesn't matter much. For example:

    sub foo { my $val; if( @_ ) { $val= shift; } else { undef $val; } return $val; } foo( "x" x 10_000 ); # 10,000 bytes of memory still tied up foo() # those 10,000 bytes now free to be reused foo( \( "x" x 10_000 ) ); # the few bytes needed to store a reference still tied up, # but the 10,000 bytes for the string value itself are # already free to be reused.

    Yes, closures never being freed is a bug due to Perl itself making a circular reference. I believe this has already been fixed. Your example code should not leak memory whether you consider it reasonable for that to happen or not. (:

            - tye (but my friends call me "Tye")
      Sorry to be contradictory. We're both saying pretty much the same thing, with slight variations. Your sample code is a good example, but I think it just shows that anonymous storage ( like \( "x" x 10_000 ) ) gets freed right away. I think it would not be freed if you had used a named scalar for that instead.

      My sample code above does leak. You have to run it in a loop to see it, because it only leaks a little each time.