I've been documenting a phenomenal number of things lately;
e.g. perltie is getting to be nearly a FMTEYEWTK.
Here's a section I recently added I thought some of you
might be interested in. I'm probably unintentionally lying
here at some point, but I'm trusting Larry to set me straight.
Any ideas where this should go? L<perlobj> is my current best
place.
--tom
=head2 Two-Phased Garbage Collection
For most purposes, Perl uses a fast and simple reference-based
garbage collection system. For this reason, there's an extra
dereference going on at some level, so if you haven't built
your Perl executable using your C compiler's C<-O> flag, performance
will suffer. If you I<have> built Perl with C<cc -O>, then this
probably won't matter.
A more serious concern is that unreachable memory with a non-zero
reference count will not normally get freed. Therefore, this is a bad
idea:
{ my $a; $a = \$a; }
Even thought $a I<should> go away, it can't. When building recursive data
structures, you'll have to break the self-reference yourself explicitly
if you don't care to leak. For example, here's a self-referential
node such as one might use in a sophisticated tree structure:
sub new_node {
my $node = {};
$node->{LEFT} = $node->{RIGHT} = $node;
$node->{DATA} = [ @_ ];
return $node;
}
If you create nodes like that, they won't go away unless you break their
self reference yourself.
Almost.
When an interpreter thread finally shuts down (usually when your program
exits), then a rather costly but complete mark-and-sweep style of garbage
collection is performed, and everything allocated by that thread gets
destroyed. This is essential to support Perl as an embedded or a
multithreadable language. For example, this program demonstrates Perl's
two-phased garbage collection:
#!/usr/bin/perl
package Subtle;
sub new {
my $test;
$test = \$test;
warn "CREATING " . \$test;
return bless \$test;
}
sub DESTROY {
my $self = shift;
warn "DESTROYING $self";
}
package main;
warn "starting program";
{
my $a = Subtle->new;
my $b = Subtle->new;
$$a = 0; # break selfref
warn "leaving block";
}
warn "just exited block";
warn "time to die...";
exit;
When run as F</tmp/test>, the following output is produced:
starting program at /tmp/test line 18.
CREATING SCALAR(0x8e5b8) at /tmp/test line 7.
CREATING SCALAR(0x8e57c) at /tmp/test line 7.
leaving block at /tmp/test line 23.
DESTROYING Subtle=SCALAR(0x8e5b8) at /tmp/test line 13.
just exited block at /tmp/test line 26.
time to die... at /tmp/test line 27.
DESTROYING Subtle=SCALAR(0x8e57c) during global destruction.
Notice that "global destruction" bit there? That's the thread
garbage collector reaching the unreachable.
e.g. perltie is getting to be nearly a FMTEYEWTK.
Here's a section I recently added I thought some of you
might be interested in. I'm probably unintentionally lying
here at some point, but I'm trusting Larry to set me straight.
Any ideas where this should go? L<perlobj> is my current best
place.
--tom
=head2 Two-Phased Garbage Collection
For most purposes, Perl uses a fast and simple reference-based
garbage collection system. For this reason, there's an extra
dereference going on at some level, so if you haven't built
your Perl executable using your C compiler's C<-O> flag, performance
will suffer. If you I<have> built Perl with C<cc -O>, then this
probably won't matter.
A more serious concern is that unreachable memory with a non-zero
reference count will not normally get freed. Therefore, this is a bad
idea:
{ my $a; $a = \$a; }
Even thought $a I<should> go away, it can't. When building recursive data
structures, you'll have to break the self-reference yourself explicitly
if you don't care to leak. For example, here's a self-referential
node such as one might use in a sophisticated tree structure:
sub new_node {
my $node = {};
$node->{LEFT} = $node->{RIGHT} = $node;
$node->{DATA} = [ @_ ];
return $node;
}
If you create nodes like that, they won't go away unless you break their
self reference yourself.
Almost.
When an interpreter thread finally shuts down (usually when your program
exits), then a rather costly but complete mark-and-sweep style of garbage
collection is performed, and everything allocated by that thread gets
destroyed. This is essential to support Perl as an embedded or a
multithreadable language. For example, this program demonstrates Perl's
two-phased garbage collection:
#!/usr/bin/perl
package Subtle;
sub new {
my $test;
$test = \$test;
warn "CREATING " . \$test;
return bless \$test;
}
sub DESTROY {
my $self = shift;
warn "DESTROYING $self";
}
package main;
warn "starting program";
{
my $a = Subtle->new;
my $b = Subtle->new;
$$a = 0; # break selfref
warn "leaving block";
}
warn "just exited block";
warn "time to die...";
exit;
When run as F</tmp/test>, the following output is produced:
starting program at /tmp/test line 18.
CREATING SCALAR(0x8e5b8) at /tmp/test line 7.
CREATING SCALAR(0x8e57c) at /tmp/test line 7.
leaving block at /tmp/test line 23.
DESTROYING Subtle=SCALAR(0x8e5b8) at /tmp/test line 13.
just exited block at /tmp/test line 26.
time to die... at /tmp/test line 27.
DESTROYING Subtle=SCALAR(0x8e57c) during global destruction.
Notice that "global destruction" bit there? That's the thread
garbage collector reaching the unreachable.