in reply to Re: Re: Memory usage breakup
in thread Memory usage breakup

Update: as pointed out by sgifford, the repeat operator isn't getting constant-folded, so most of this is wrong - it is the pad entry for the subexpression mentioned in the last two paragraphs that is grabbing the memory.
End update

The 10MB string in $x is freed by the undef $x, but there is another copy of the string attached to the optree (the compiled code), since constant folding will replace

my $x = "A" x 10_000_000;
with
my $x = "AAAAA..[10_000_000 long]..";

You can test this by putting the code in an anonymous sub, and then freeing it:

our $x; my $code = sub { $x = "A" x 10_000_000 }; showmem("start"); &$code; showmem("allocated"); undef $x; showmem("var freed"); undef $code; showmem("code freed");

Running that here shows VMSize at each step of:

start: 2896 kB
allocated: 22436 kB
var freed: 12668 kB
code freed: 2900 kB

However, I feel that it is quite rare to have big constants like this in real code, so the simplistic approach of "fold anything that's constant" is still probably the right thing for perl to do.

Unfortunately you cannot sidestep this just by replacing the constants with variables, since then a different aspect kicks in: perl's compiler assigns an entry on the pad for the results of subexpressions, and this intermediate target then holds the extra copy of the string.

I'm not sure whether any of the pad-peeking CPAN modules show these unnamed pad entries, but the -DX debugging flag will help at least to verify their existence, eg:

perl -DXt -we 'my $l = 100; my $a = "A" x $l;'

Hugo

Replies are listed 'Best First'.
Re: Re: Re: Re: Memory usage breakup
by sgifford (Prior) on May 01, 2004 at 15:48 UTC
    Huh. I just tried your code and got the same results. I find that surprising; I would expect constant folding to happen at compile time, and so for the memory to be allocated at the start step.

      You're right, I would have expected that too. Looking more closely, it turns out that it doesn't get constant-folded at all - I guess the repeat operator isn't included for that optimisation.

      (I checked by modifying the code to call the coderef twice, and then examined the trace produced by perl -Dt.)

      So it would appear that it is just the anonymous pad variable for the subexpression target that is grabbing the memory.

      Hugo