I'm doing some research in perl's (and by extension mod_perl's) use of
memory.  I recently used the terrific B::TerseSize module to profile a
number of modules used in my server and found some discrepency in
sizes.  The total bytes used was greater than the sum of the
individual elements.

Digging deeper I found that the module in question initialized a
package variable when the module was loaded.  I moved the code into a
BEGIN block and the memory usage dropped.

I then performed a test case (see below) and verified that this is the
case.

I've not seen this mentioned as of yet, but I think it's a useful
technique to reduce the memory constraints of your mod_perl based
server.

Of course, this begs the question, why doesn't Perl free up the memory
of code placed inside modules?


Anyway, here's the proof, done on a RedHat 7.1 system with perl 5.6.0.
The module TestMem (attached) was run with and without inititialization
code in a BEGIN block.  To test I ran

perl -MTestMem -e 'TestMem::foo'

I then compared the output of the /proc/PID/statm

The results, without and with a BEGIN block are:

  305 305 261 117 0 188 44
  296 296 251 118 0 178 45

The fields here are: 

  size       total program size
  resident   size of in memory portions
  shared     number of the pages that are shared
  trs        number of pages that are 'code'
  drs        number of pages of data/stack
  lrs        number of pages of library
  dt         number of dirty pages


So, we save about 9k just by moving code into a BEGIN block for this
simple example..



----------------------------------------------------------------------
package TestMem;

my $a = 1;
my $b = 10;

#BEGIN {
$a = $a + 10; 
$a = $a * 10; $a = $a / 9; $a = $a * 10; $a = $a / 9;
$a = $a * 10; $a = $a / 9; $a = $a * 10; $a = $a / 9;
$a = $a * 10; $a = $a / 9; $a = $a * 10; $a = $a / 9;

$b = $b * 100; $b = $b / 100; $b = $b * 100; $b = $b / 100; 
$b = $b * 100; $b = $b / 100; $b = $b * 100; $b = $b / 100;
$b = $b * 100; $b = $b / 100; $b = $b * 100; $b = $b / 100;
$b = $b * 100; $b = $b / 100; $b = $b * 100; $b = $b / 100;
$b = $b * 100; $b = $b / 100; $b = $b * 100; $b = $b / 100;
$b = $b * 100; $b = $b / 100; $b = $b * 100; $b = $b / 100;

#  }  # end begin..

sub foo {
  my $c = " " x 10000;  # hopefully reallocate freed mem...
  print "pid $$ : $a $b";
  sleep(10000000);
}
1;




-- 
Paul Lindner
[EMAIL PROTECTED]

Reply via email to