in reply to Memory leaks and circular references

It's reasonably straightforward. Every time you take a reference to something, Perl increments its reference count by one. Every time you get rid of a reference to something, Perl decrements its reference count by one. When the reference count reaches zero, Perl recycles the item, because nothing else refers to it.

For the purpose of this discussion, read "take a reference to" as meaning "use in a way that you want to keep it around" -- closing over a lexical variable counts, for example.

The problem with that, which your first example shows, is when two items refer to each other. The object referrred to by $top has two references, one from the lexical variable and one from the contained Bottom object. The Bottom object has one reference, from the $top object. Their reference counts will never reach zero and Perl will never reclaim them because they refer to each other.

The solution is to make one of the references a weak reference. A weak reference refers to another item but does not increment its reference count when you first refer to it, nor does it decrement its reference count when the weak reference goes away.

The problem in your second example is that you made both references weak references far too early, so when the reference count to the Bottom object reached zero (that is, when you weakened the reference), Perl cleaned it up.

Your code would work if you made $top a weak reference within the Bottom constructor, as you have other references keeping $top active but nothing else keeping the Bottom object active.

Replies are listed 'Best First'.
Re^2: Memory leaks and circular references
by jdrago_999 (Hermit) on Sep 06, 2008 at 22:14 UTC
    chromatic -

    Thank you for taking the time for such a thorough explanation.

    I never quite understood it, but now I do.