A technique I used to allow testing code to verify correct object destruction of some classes that use weak references to break cycles was something like:
package Whatever;
sub new {
my $class = shift;
my $ob = {};
# ...
{ our $_total_constructed; $_total_constructed++ }
bless $ob, $class
}
sub DESTROY { our $_total_destroyed; $_total_destroyed++ }
The test scripts can then access those package variables and verify that $Whatever::_total_constructed and $Whatever::_total_destroyed are equal at the end of a test run after the last lexical holding an object has gone out of scope.