Circular References In Perl Memory Leaks

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.