オブジェクトの1つに循環参照を含めることができます。ガベージコレクターがこのオブジェクトの割り当てを解除するためにやってくると、循環参照は、その参照によって参照されるすべてのものが解放されることは決してないことを意味します。Devel::CycleおよびTest::Memory::Cycleを使用して循環参照を確認できます。試してみる1つのこと(本番コードではコストがかかる可能性があるため、デバッグフラグが設定されていない場合は無効にします)は、すべてのオブジェクトのデストラクタ内の循環参照をチェックすることです。
# make this be the parent class for all objects you want to check;
# or alternatively, stuff this into the UNIVERSAL class's destructor
package My::Parent;
use strict;
use warnings;
use Devel::Cycle; # exports find_cycle() by default
sub DESTROY
{
my $this = shift;
# callback will be called for every cycle found
find_cycle($this, sub {
my $path = shift;
foreach (@$path)
{
my ($type,$index,$ref,$value) = @$_;
print STDERR "Circular reference found while destroying object of type " .
ref($this) . "! reftype: $type\n";
# print other diagnostics if needed; see docs for find_cycle()
}
});
# perhaps add code to weaken any circular references found,
# so that destructor can Do The Right Thing
}