Subject: | Memory-leak (cycle) with constraints/compiled_type_constraint members and $self |
The 'constraint' key points to a function which gets $self through
closure, resulting in a cycle. Similar for 'compiled_type_constraints'.
Using Scalar::Util::weaken() on $self in generate_constraint_for fixes
the problem as far as I know.
Cycle (3):
$Class::MOP::Class::Immutable::Moose::Meta::Class::A->
{'methods'} => \%B
$B->{'execute'} => \
%MooseX::Method::Signatures::Meta::Method::C
$MooseX::Method::Signatures::Meta::Method::C->
{'parsed_signature'} => \%Parse::Method::Signatures::Sig::D
$Parse::Method::Signatures::Sig::D->{'_positional_params'} => \
%Parse::Method::Signatures::ParamCollection::E
$Parse::Method::Signatures::ParamCollection::E->{'params'} =>
\@F
$F->[0] => \
%Class::MOP::Class::__ANON__::SERIAL::5::G
$Class::MOP::Class::__ANON__::SERIAL::5::G->{'__MOP__'} => \
%Moose::Meta::Class::H
$Moose::Meta::Class::H->{'_meta_instance'} => \
%Moose::Meta::Instance::I
$Moose::Meta::Instance::I->{'attributes'} =>
\@J
$J->[4] => \%Moose::Meta::Attribute::K
$Moose::Meta::Attribute::K->{'isa'} => \
%MooseX::Types::TypeDecorator::L
$MooseX::Types::TypeDecorator::L->{'__type_constraint'} => \
%Moose::Meta::TypeConstraint::Parameterized::L
$Moose::Meta::TypeConstraint::Parameterized::L->
{'type_parameter'} => \%MooseX::Types::TypeDecorator::U
$MooseX::Types::TypeDecorator::U->{'__type_constraint'} => \
%MooseX::Meta::TypeConstraint::Structured::U
$MooseX::Meta::TypeConstraint::Structured::U->{'constraint'} =>
\&S
$S variable $self => \$T
$$T => \
%MooseX::Meta::TypeConstraint::Structured::U
-------------------------------------------
Cycle (3):
$Class::MOP::Class::Immutable::Moose::Meta::Class::A->
{'methods'} => \%B
$B->{'execute'} => \
%MooseX::Method::Signatures::Meta::Method::C
$MooseX::Method::Signatures::Meta::Method::C->
{'parsed_signature'} => \%Parse::Method::Signatures::Sig::D
$Parse::Method::Signatures::Sig::D->{'_positional_params'} => \
%Parse::Method::Signatures::ParamCollection::E
$Parse::Method::Signatures::ParamCollection::E->{'params'} =>
\@F
$F->[0] => \
%Class::MOP::Class::__ANON__::SERIAL::5::G
$Class::MOP::Class::__ANON__::SERIAL::5::G->{'__MOP__'} => \
%Moose::Meta::Class::H
$Moose::Meta::Class::H->{'_meta_instance'} => \
%Moose::Meta::Instance::I
$Moose::Meta::Instance::I->{'attributes'} =>
\@J
$J->[4] => \%Moose::Meta::Attribute::K
$Moose::Meta::Attribute::K->{'isa'} => \
%MooseX::Types::TypeDecorator::L
$MooseX::Types::TypeDecorator::L->{'__type_constraint'} => \
%Moose::Meta::TypeConstraint::Parameterized::L
$Moose::Meta::TypeConstraint::Parameterized::L->
{'type_parameter'} => \%MooseX::Types::TypeDecorator::U
$MooseX::Types::TypeDecorator::U->{'__type_constraint'} => \
%MooseX::Meta::TypeConstraint::Structured::U
$MooseX::Meta::TypeConstraint::Structured::U->
{'compiled_type_constraint'} => \&Q
$Q variable $check => \$R
$$R => \&S
$S variable $self => \$T
$$T => \
%MooseX::Meta::TypeConstraint::Structured::U