my %seek_and_destroy;
sub _arm_global_destructor {
+
+ # quick "garbage collection" pass - prevents the registry
+ # from slowly growing with a bunch of undef-valued keys
+ defined $seek_and_destroy{$_} or delete $seek_and_destroy{$_}
+ for keys %seek_and_destroy;
+
weaken (
$seek_and_destroy{ refaddr($_[0]) } = $_[0]
);
attrs => $attrs,
}, ref $class || $class;
- weaken( $cursor_registry{ refaddr($self) } = $self )
- if DBIx::Class::_ENV_::HAS_ITHREADS;
+ if (DBIx::Class::_ENV_::HAS_ITHREADS) {
+
+ # quick "garbage collection" pass - prevents the registry
+ # from slowly growing with a bunch of undef-valued keys
+ defined $cursor_registry{$_} or delete $cursor_registry{$_}
+ for keys %cursor_registry;
+
+ weaken( $cursor_registry{ refaddr($self) } = $self )
+ }
return $self;
}
# a registry could be fed to itself or another registry via recursive sweeps
return $target if $reg_of_regs{$refaddr};
+ weaken( $reg_of_regs{ hrefaddr($weak_registry) } = $weak_registry )
+ unless( $reg_of_regs{ hrefaddr($weak_registry) } );
+
+ # an explicit "garbage collection" pass every time we store a ref
+ # if we do not do this the registry will keep growing appearing
+ # as if the traced program is continuously slowly leaking memory
+ for my $reg (values %reg_of_regs) {
+ (defined $reg->{$_}{weakref}) or delete $reg->{$_}
+ for keys %$reg;
+ }
+
if (! defined $weak_registry->{$refaddr}{weakref}) {
$weak_registry->{$refaddr} = {
stacktrace => stacktrace(1),
$weak_registry->{$refaddr}{slot_names}{$note} = 1;
}
- weaken( $reg_of_regs{ hrefaddr($weak_registry) } = $weak_registry )
- unless( $reg_of_regs{ hrefaddr($weak_registry) } );
-
$target;
}