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