What Is A Memory Leak?
Quoting
Wikipedia
:
| A memory leak is a particular kind of unnecessary memory consumption by a computer program, where the program fails to release memory that is no longer needed. The term is somewhat of a misnomer, since memory is not leaked or lost from the computer, but rather no longer available for use. |
Perl applications like TWiki use quite a lot of memory. However, in the conventional usage of TWiki as a
CGI program, this doesn't hurt (or better: doesn't hurt
much). Every request starts a new perl interpreter, and at the end of the processing all RAM is returned to the operating systems.
Things are different if you are running a perl process for a long time, like if using an accelerator like
ModPerl or
PersistentPerl. These avoid having to start a new perl interpreter for every HTTP request by always keeping the same instance of an interpreter around, and just pass the
CGI programs to this interpreter. This means that:
- Compilation of your source is done just once (that's where the main performance gain comes from in TWiki)
- There is no termination of the process after your request is done.
The second part is important for our consideration, mainly due to the rather primitive
garbage collection in Perl
.
If a perl program doesn't terminate, it doesn't do its final, sophisticated garbage collection - and only frees memory for objects with
no (zero) references pointing to it.
I'm not going to go into more detail about this since it has been discussed at length by perl developers for years, and just provide a simple example:
sub bad_idea {
my $a = {};
my $b = {};
$b->{a} = $a;
$a->{b} = $b
}
In this example,
$a holds a reference to
$b and vice versa. At the end of the
sub, one would expect both
$a and
$b to vanish into thin air - only that they don't. When Perl wants to release the memory occupied by
$a, it says "wait - there's still a reference to it somewhere". And it won't free
$b because there's still a pointer to it as well. Since neither
$a nor
$b are freed, the situation is unchanged - and Perl stops trying.
Circular references are by far the most frequent cause of memory leak in Perl programs.
Watch for those circular references, avoid them, and if you can't, make sure that before leaving the lexical scope of both
$a and
$b the circle is broken - for example by simply deleting one of the references:
sub bad_idea_repaired {
my $a = {};
my $b = {};
$b->{a} = $a;
$a->{b} = $b
# ...do stuff ...
delete $a->{b} # hooray - no more circle. $b gets freed, and then $a.
}
--
Contributors: HaraldJoerg
Discussion
On occasion. Looks as if TWiki 4.0 leaks memory at the time of this writing. See
Bugs:Item2158
and
HowToTrackDownCircularReferences.
--
HaraldJoerg - 26 Apr 2006