Circular references are one the canonical causes of memory leaks. The reason is due to the flexibility provided by the Perl to use the variables, references, etc. Perl uses reference counting garbage collection. This means that Perl keeps a count of what pointers to any variable exist at a given time. If the variable goes out of scope and the count is 0, the variable is cleared.
sub leak {
my ($foo, $bar);
$foo = \$bar;
$bar = \$foo;
}
In the example code above, $foo
and $bar
are having reference to the other. When the function leak()
finishes, the variables $foo
and $bar
will go out of the scope. It will never be collected. They won’t be destroyed and removed from memory as each one still has a reference leading to it.
The easiest way to prevent this issue is to use weak references. Weak references are references that we should use to access data, but do not count for garbage collection.
use Scalar::Util qw(weaken);
sub dont_leak {
my ($foo, $bar);
$foo = \$bar;
$bar = \$foo;
weaken $bar;
}
In dont_leak()
, $foo
has a reference count of 0, $bar
has a ref count of 1. When we leave the scope of the subroutine, $foo
is returned to the pool, and its reference to $bar
is cleared. This drops the ref count on $bar
to 0, which means that $bar
can also return to the pool.