On Saturday 12 December 2009 00:24:24 Perrin Harkins wrote:
> Perl will keep the memory and reuse it for that exact same lexical
> variable the next time you enter that section of code.  It's a
> performance optimization that is usually a good thing, unless you put
> a lot of data in one lexical in some code that you rarely run.
> 
perhaps an example can help to shed some light. To understand it you have to
know that many malloc implementations allocate large chunks of memory via
mmap() while smaller pieces are allocated via brk(). The mmap-allocated
blocks can later be returned to the OS while the brk-allocated can not.

So, here is the example. It creates a large string (10 mbytes) and assigns it
to the variable $x. This means another 10mb chunk is allocated to keep the
variable. Devel::Peek::Dump is used to show the address of the string assigned
to the variable.

Now look what is when freed:

strace perl -MDevel::Peek -e '{my $x="x"x(10*1024*1024); $x=""; Dump $x; undef 
$x; warn 1;} warn 2'

Here 2 memory blocks are allocated. One is the "x"x(10*1024*1024) string the
other is the PV-member of $x. It seems to be logical that the second one is
$x but let's see ...

mmap(NULL, 10489856, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0x7ff87f08a000
mmap(NULL, 10489856, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0x7ff87e689000

These write()s come from Dump $x. The PV=0x7ff87e689028 line below is of
particular interest. It shows that the memory block at 0x7ff87e689000
in fact belongs to $x.

write(2, "SV = ", 5SV = )                    = 5
write(2, "PV(0x78bcb0) at 0x78ef78\n  REFCN"..., 65PV(0x78bcb0) at 0x78ef78
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
) = 65
write(2, "  PV = 0x7ff87e689028 ", 22  PV = 0x7ff87e689028 )  = 22
write(2, "\"\"\\0", 4""\0)                  = 4
write(2, "\n", 1
)                       = 1
write(2, "  CUR = 0\n", 10  CUR = 0
)             = 10
write(2, "  LEN = 10485768\n", 17  LEN = 10485768
)      = 17

The next syscall comes from undef $x. Here the second allocated block is
freed and returned to the OS.

munmap(0x7ff87e689000, 10489856)        = 0

This write() is the "warn 1"

write(2, "1 at -e line 1.\n", 161 at -e line 1.
)       = 16

And this the "warn 2". You see the memory block allocated to keep the
"x"x(10*1024*1024) string is still kept by the program even though the
scope where it has been allocated is finished.

write(2, "2 at -e line 1.\n", 162 at -e line 1.
)       = 16

Only right before finishing the program the "x"x(10*1024*1024) string
is freed.

munmap(0x7ff87f08a000, 10489856)        = 0
exit_group(0)                           = ?


Now, omit the "undef $x" and see when the memory allocated to the variable
is freed.

Torsten

Reply via email to