Nested Function Calls, Recursion, and Memory

RSuh at aol.com RSuh at aol.com
Fri Dec 20 18:16:41 CST 2002


~sdpm~
At the last meeting, i had a small recursive script which "seemed" like it was leaking, or not releasing memory. Asking around, i found out that it was not leaking, but still not releasing memory, im assuming so it can reuse it if i called it again later..

I used Devel::Leak to count the blocks allocated..

Test1: Nested Function Call

CountBlocks Start
Function A calls Function B
CountBlocks End

no additional blocks allocated.

Test2 : 2 level deep recursive call

CountBlocks Start
Function A calls Function A, then returns out..
CountBlocks End

88 blocks allocated..

Executing the calls in a loop, does not accumulate additional blocks, which kinda proves that is not "leaking"..

>From what i can gather, and i still need to do some more research on this, Perl has a global memory area for variables defined, and as long has your program doesnt use any variables already allocated in this area, it will not allocate more memory..

This idea follows with my tests.. Since function A is never called again before Function A exists.. the memory can stay in this "global" area.. no variables were stomped on.. thus no need to allocate more..

Test2 : the recursive call.. Function As variables are stepped on when Function A calls Function A.. Thus Perl needs to allocate more memory each time it nests on itself.... Why it doesnt free it when it leaves the scope is beyond me..

So what i learned.. dont do recursion if memory is an issue.. it will eat alot depending on how deep u go.. If you need to use recursion, keep the amount of variables used in the function low, since they wont be released (but will be reused if you call it again)..

my 2 cents..
--rob

Im on Win2k, ActiveState 6.5.1..

below is my test script...

use strict;
sub cat($)
{
   my $var = shift;
   print "cat ($var)\n";

}

sub bat($)
{
   my $var=shift;
   print "bat ($var)\n";
   cat($var);

}

sub apple($)
{
   my $hello=shift;
   print "Apple ($hello)\n";
   bat($hello);
}


sub recurse($)
{
   my $count=shift;

   print "0Count = ($count)\n";
   if ($count >= 1)
   {
      undef($count);
      print "Leaving...\n";
      return;
   }
   $count++;
   recurse($count);
}

sub recurse1($)
{
   my $count=shift;

   print "Count1 = ($count)\n";
   if ($count >= 1)
   {
      undef($count);
      print "Leaving...\n";
      return;
   }
   $count++;
   recurse2($count);
}

sub recurse2($)
{
   my $count=shift;

   print "Count2 = ($count)\n";
   if ($count >= 1)
   {
      undef($count);
      print "Leaving...\n";
      return;
   }
   $count++;
}

print "GetAll Test\n";
   
   use Devel::Leak;
   my $handle;
   my $count = Devel::Leak::NoteSV($handle);
   print "Memory Count Start = ($count)\n";

   # this loop is here to test accumulation of memory..
   # by increasing the loop max, it does not accumulate
   #  more memory usage.. it _seems_ to reuse....the
   #  results do not change..
  for (my $xx=0; $xx< 1; $xx++)
  {
     recurse(0);       # leaky toilet
    # recurse1(0);    # no leak
    # apple(1);       # no leaks           
  }



  my $count1= Devel::Leak::CheckSV($handle); 
  my $diff = $count1- $count; 
      
  print "\nCount = ($count1)\n";
  print "Difference in Memory = ($diff)\n";

#=== END----






~sdpm~

The posting address is: san-diego-pm-list at hfb.pm.org

List requests should be sent to: majordomo at hfb.pm.org

If you ever want to remove yourself from this mailing list,
you can send mail to <majordomo at happyfunball.pm.org> with the following
command in the body of your email message:

    unsubscribe san-diego-pm-list

If you ever need to get in contact with the owner of the list,
(if you have trouble unsubscribing, or have questions about the
list itself) send email to <owner-san-diego-pm-list at happyfunball.pm.org> .
This is the general rule for most mailing lists when you need
to contact a human.




More information about the San-Diego-pm mailing list