summaryrefslogtreecommitdiff
path: root/pod/perlref.pod
diff options
context:
space:
mode:
authorDave Rolsky <autarch@urth.org>2011-07-05 22:09:19 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-07-05 22:11:58 -0700
commit0a044a7cc96a996b26b8d31caa93c9627fa49e9e (patch)
tree633fe731c96a4ec47fa883d8f1a421b726bf9b43 /pod/perlref.pod
parent615d795d657ccfcad8a25f1adf594120d271288a (diff)
downloadperl-0a044a7cc96a996b26b8d31caa93c9627fa49e9e.tar.gz
Add section on circular refs to perlref
Diffstat (limited to 'pod/perlref.pod')
-rw-r--r--pod/perlref.pod52
1 files changed, 52 insertions, 0 deletions
diff --git a/pod/perlref.pod b/pod/perlref.pod
index 550f4c14d2..f45a3836e2 100644
--- a/pod/perlref.pod
+++ b/pod/perlref.pod
@@ -458,6 +458,58 @@ as:
print "That yields ${\($n + 5)} widgets\n";
+=head2 Circular References
+X<circular reference> X<reference, circular>
+
+It is possible to create a "circular reference" in Perl, which can lead
+to memory leaks. A circular reference occurs when two references
+contain a reference to each other, like this:
+
+ my $foo = {};
+ my $bar = { foo => $foo };
+ $foo->{bar} = $bar;
+
+You can also create a circular reference with a single variable:
+
+ my $foo;
+ $foo = \$foo;
+
+In this case, the reference count for the variables will never reach 0,
+and the references will never be garbage-collected. This can lead to
+memory leaks.
+
+Because objects in Perl are implemented as references, it's possible to
+have circular references with objects as well. Imagine a TreeNode class
+where each node references its parent and child nodes. Any node with a
+parent will be part of a circular reference.
+
+You can break circular references by creating a "weak reference". A
+weak reference does not increment the reference count for a variable,
+which means that the object can go out of scope and be destroyed. You
+can weaken a reference with the C<weaken> function exported by the
+L<Scalar::Util> module.
+
+Here's how we can make the first example safer:
+
+ use Scalar::Util 'weaken';
+
+ my $foo = {};
+ my $bar = { foo => $foo };
+ $foo->{bar} = $bar;
+
+ weaken $foo->{bar};
+
+The reference from C<$foo> to C<$bar> has been weakened. When the
+C<$bar> variable goes out of scope, it will be garbage-collected. The
+next time you look at the value of the C<< $foo->{bar} >> key, it will
+be C<undef>.
+
+This action at a distance can be confusing, so you should be careful
+with your use of weaken. You should weaken the reference in the
+variable that will go out of scope I<first>. That way, the longer-lived
+variable will contain the expected reference until it goes out of
+scope.
+
=head2 Symbolic references
X<reference, symbolic> X<reference, soft>
X<symbolic reference> X<soft reference>