Skip Menu |

This queue is for tickets about the MooseX-Role-Parameterized CPAN distribution.

Report information
The Basics
Id: 65709
Status: rejected
Priority: 0/
Queue: MooseX-Role-Parameterized

People
Owner: Nobody in particular
Requestors: j.bonte [...] legian.nl
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.23
Fixed in: (no value)



Subject: memory leak when MooseX::Role::Parameterized is used from inside BUILD
System: MooseX::Role::Parameterized-0.23 Perl v8.5.7 SunOS 5.8 Problem: MooseX::Role::Parameterized has a memory leak, when it is invoked other than through a direct 'with'. Example code: package Test::Role; use MooseX::Role::Parameterized; parameter function_name => ( required => 1, isa => 'Str', is => 'ro', ); role { my $parameter = shift; my $function_name = $parameter->function_name; method "$function_name" => sub { my $self = shift; return "The stored text for function '$function_name' = 'memory leak tester'\n"; }; }; package Test::Attribute; use Moose; # 1, no leak #with('Test::Role' => { function_name => 'get_text' }); # 2, leaks #sub BUILD {with('Test::Role' => {function_name => 'get_text' })}; package main; for ( my $i = 1; $i <= 1000; $i++ ) { my $test = Test::Attribute->new( { } ); print $test->get_text; } 1; Uncomment '1, no leak' line to run 'test' 1000 times - memory stays at 10 MB Uncomment '2, leaks' line to run 'test' 1000 times - memory slowly increases from 10 MB to 17 MB - Code is running about a factor 100 slower
On Mon Feb 14 06:53:56 2011, j.bonte@legian.nl wrote: Show quoted text
> #sub BUILD {with('Test::Role' => {function_name => 'get_text' })};
I don't know what you think this does, but what it actually does is apply the role to the entire class every time you instantiate an object. That's almost certainly not what you want, but since you gave a trivial fake example, I don't know what you do want. (Maybe you wanted Moose::Util::apply_all_roles with $self.) Also, this isn't a memory leak. It just generates more and more data, so more memory is used. It's no different from something like this: my $stuff; sub BUILD { $stuff .= "1234567890" }
Subject: Re: [rt.cpan.org #65709] memory leak when MooseX::Role::Parameterized is used from inside BUILD
Date: Mon, 14 Feb 2011 16:51:56 +0100
To: bug-MooseX-Role-Parameterized [...] rt.cpan.org
From: Jari Bonte <j.bonte [...] legian.nl>
Hi, I have attempted to give an example with minimal code that leakes memory. While doing that I tried to keep the 'leaking' and 'non-leaking' code as close as possible. It is unfortunate that this resulted in non-sense.. Perhaps this is a better example: package Test::Role; use MooseX::Role::Parameterized; parameter function_name => ( required => 1, isa => 'Str', is => 'ro', ); parameter default_value => ( required => 1, isa => 'Int', is => 'ro', ); role { my $parameter = shift; my $function_name = $parameter->function_name; my $default_value = $parameter->default_value; method "$function_name" => sub { return $default_value; }; }; package Test::Attribute; use Moose; use Moose::Util qw( apply_all_roles ); has default1 => ( required => 1, isa => 'Int', is => 'ro', ); has default2 => ( required => 1, isa => 'Int', is => 'ro', ); sub BUILD { } after BUILD => sub { my $self = shift; apply_all_roles( $self, 'Test::Role' => { function_name => 'Armor_strength', default_value => $self->default1 }, 'Test::Role' => { function_name => 'Weapon_strength', default_value => $self->default2 }, ); }; package main; for ( my $i = 1; $i <= 10000; $i++ ) { my $def1 = int( rand(100) ); my $def2 = int( rand(100) ); my $test = Test::Attribute->new( { default1 => $def1, default2 => $def2 } ); print "User $i has armor: " . $test->Armor_strength . " and weapon " . $test->Weapon_strength . "\n"; } 1; A single role that is functioning as a counter The role is applied twice to each instance of a new Attribute using different values for each attribute. But when the attribute goes out of scope the memory is not cleared. I hope this gives a better idea on what I'm trying to do. 2011/2/14 Hans Dieter Pearcey via RT < bug-MooseX-Role-Parameterized@rt.cpan.org> Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=65709 > > > On Mon Feb 14 06:53:56 2011, j.bonte@legian.nl wrote:
> > #sub BUILD {with('Test::Role' => {function_name => 'get_text' })};
> > I don't know what you think this does, but what it actually does is > apply the role to the entire class every time you instantiate an > object. > > That's almost certainly not what you want, but since you gave a > trivial fake example, I don't know what you do want. (Maybe you > wanted Moose::Util::apply_all_roles with $self.) > > Also, this isn't a memory leak. It just generates more and more data, > so more memory is used. It's no different from something like this: > > my $stuff; > sub BUILD { $stuff .= "1234567890" } > > >
On Mon Feb 14 10:52:08 2011, j.bonte@legian.nl wrote: Show quoted text
> The role is applied twice to each instance of a new Attribute using > different values for each attribute. > But when the attribute goes out of scope the memory is not cleared.
Using MXRP gives you anonymous roles. Does this happen with regular anonymous roles (e.g. Moose::Meta::Role->create_anon_role)? Looking at the code, I think it may be a bug in Moose rather than in MXRP.
Subject: Re: [rt.cpan.org #65709] memory leak when MooseX::Role::Parameterized is used from inside BUILD
Date: Tue, 15 Feb 2011 12:02:58 +0100
To: bug-MooseX-Role-Parameterized [...] rt.cpan.org
From: Jari Bonte <j.bonte [...] legian.nl>
Hi, I have not had much practice with anonymous roles, but I did some testing and came up with the following: package Test::Attribute; use Moose; use Moose::Util qw( apply_all_roles ); has default1 => ( required => 1, isa => 'Int', is => 'ro', ); has default2 => ( required => 1, isa => 'Int', is => 'ro', ); sub BUILD { } after BUILD => sub { my $self = shift; apply_all_roles( $self, Moose::Meta::Role->create_anon_role( attributes => { default_value => { is => 'ro', isa => 'Int', required => 1, default => $self->default1, }, }, methods => { Armor_strength => sub { return shift->default_value }, }, ) ); apply_all_roles( $self, Moose::Meta::Role->create_anon_role( attributes => { default_value => { is => 'ro', isa => 'Int', required => 1, default => $self->default2, }, }, methods => { Weapon_strength => sub { return shift->default_value }, }, ) ); }; package main; for ( my $i = 1 ; $i <= 10000 ; $i++ ) { my $def1 = int( rand(100) ); my $def2 = int( rand(100) ); my $test = Test::Attribute->new( { default1 => $def1, default2 => $def2 } ); print "User $i has armor: " . $test->Armor_strength . " and weapon " . $test->Weapon_strength . "\n"; } 1; This works, and does indeed leak memory. Hopefully I can find a way to make this work without the memory leak. 2011/2/14 Hans Dieter Pearcey via RT < bug-MooseX-Role-Parameterized@rt.cpan.org> Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=65709 > > > On Mon Feb 14 10:52:08 2011, j.bonte@legian.nl wrote:
> > The role is applied twice to each instance of a new Attribute using > > different values for each attribute. > > But when the attribute goes out of scope the memory is not cleared.
> > Using MXRP gives you anonymous roles. Does this happen with regular > anonymous roles (e.g. Moose::Meta::Role->create_anon_role)? Looking at > the code, I think it may be a bug in Moose rather than in MXRP. >
Subject: Re: [rt.cpan.org #65709] memory leak when MooseX::Role::Parameterized is used from inside BUILD
Date: Tue, 15 Feb 2011 09:11:31 -0500
To: bug-MooseX-Role-Parameterized [...] rt.cpan.org
From: Stevan Little <stevan.little [...] iinteractive.com>
I am not sure this is a memory leak, for *every* instance of Test::Attribute you create, you are also creating 2 meta-role objects, each with an attribute meta-object, which when applied in the way you are doing it (using two separate calls to apply_all_roles) will create 2 anon-class objects which will cause 2 packages to be eval-ed into existence. This means that for every instance you create you are also creating 6 other objects, which means for the 1000 objects you intended to create, you have also created another 5000 more for a grant total of 6000. Now, that said, I think the Moose core team was looking into proper anon-role cleanup/destruction, but I think while that might be an issue, it is not the issue you are seeing here. I suspect this is not what you are after, and I also know for sure that there is a much better way for you to go about this. I recommend you stop by #moose on irc.perl.org or try the Moose mailing list, and discuss a better solution. - Stevan On Feb 15, 2011, at 6:03 AM, j.bonte@legian.nl via RT wrote: Show quoted text
> Queue: MooseX-Role-Parameterized > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=65709 > > > Hi, > > I have not had much practice with anonymous roles, but I did some testing > and came up with the following: > > package Test::Attribute; > use Moose; > use Moose::Util qw( apply_all_roles ); > > has default1 => ( > required => 1, > isa => 'Int', > is => 'ro', > ); > > has default2 => ( > required => 1, > isa => 'Int', > is => 'ro', > ); > > sub BUILD { } > after BUILD => sub { > my $self = shift; > apply_all_roles( > $self, > Moose::Meta::Role->create_anon_role( > attributes => { > default_value => { > is => 'ro', > isa => 'Int', > required => 1, > default => $self->default1, > }, > }, > methods => > { Armor_strength => sub { return shift->default_value }, }, > ) > ); > apply_all_roles( > $self, > > Moose::Meta::Role->create_anon_role( > attributes => { > default_value => { > is => 'ro', > isa => 'Int', > required => 1, > default => $self->default2, > }, > }, > methods => > { Weapon_strength => sub { return shift->default_value }, }, > ) > ); > }; > > package main; > for ( my $i = 1 ; $i <= 10000 ; $i++ ) { > my $def1 = int( rand(100) ); > my $def2 = int( rand(100) ); > my $test = Test::Attribute->new( { default1 => $def1, default2 => $def2 > } ); > print "User $i has armor: " . $test->Armor_strength . " and weapon " . > $test->Weapon_strength . "\n"; > } > > 1; > > This works, and does indeed leak memory. > Hopefully I can find a way to make this work without the memory leak. >
Show quoted text
> 2011/2/14 Hans Dieter Pearcey via RT < > bug-MooseX-Role-Parameterized@rt.cpan.org> >
>> <URL: https://rt.cpan.org/Ticket/Display.html?id=65709 > >> >> On Mon Feb 14 10:52:08 2011, j.bonte@legian.nl wrote:
>>> The role is applied twice to each instance of a new Attribute using >>> different values for each attribute. >>> But when the attribute goes out of scope the memory is not cleared.
>> >> Using MXRP gives you anonymous roles. Does this happen with regular >> anonymous roles (e.g. Moose::Meta::Role->create_anon_role)? Looking at >> the code, I think it may be a bug in Moose rather than in MXRP. >>
>
Subject: Re: [rt.cpan.org #65709] memory leak when MooseX::Role::Parameterized is used from inside BUILD
Date: Wed, 16 Feb 2011 08:13:52 +0100
To: bug-MooseX-Role-Parameterized [...] rt.cpan.org
From: Jari Bonte <j.bonte [...] legian.nl>
Thanks, I will have a look at the mailing list. 2011/2/15 Stevan Little via RT <bug-MooseX-Role-Parameterized@rt.cpan.org> Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=65709 > > > I am not sure this is a memory leak, for *every* instance of > Test::Attribute you create, you are also creating 2 meta-role objects, each > with an attribute meta-object, which when applied in the way you are doing > it (using two separate calls to apply_all_roles) will create 2 anon-class > objects which will cause 2 packages to be eval-ed into existence. > > This means that for every instance you create you are also creating 6 other > objects, which means for the 1000 objects you intended to create, you have > also created another 5000 more for a grant total of 6000. > > Now, that said, I think the Moose core team was looking into proper > anon-role cleanup/destruction, but I think while that might be an issue, it > is not the issue you are seeing here. > > I suspect this is not what you are after, and I also know for sure that > there is a much better way for you to go about this. I recommend you stop by > #moose on irc.perl.org or try the Moose mailing list, and discuss a better > solution. > > - Stevan > > > On Feb 15, 2011, at 6:03 AM, j.bonte@legian.nl via RT wrote: >
> > Queue: MooseX-Role-Parameterized > > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=65709 > > > > > Hi, > > > > I have not had much practice with anonymous roles, but I did some testing > > and came up with the following: > > > > package Test::Attribute; > > use Moose; > > use Moose::Util qw( apply_all_roles ); > > > > has default1 => ( > > required => 1, > > isa => 'Int', > > is => 'ro', > > ); > > > > has default2 => ( > > required => 1, > > isa => 'Int', > > is => 'ro', > > ); > > > > sub BUILD { } > > after BUILD => sub { > > my $self = shift; > > apply_all_roles( > > $self, > > Moose::Meta::Role->create_anon_role( > > attributes => { > > default_value => { > > is => 'ro', > > isa => 'Int', > > required => 1, > > default => $self->default1, > > }, > > }, > > methods => > > { Armor_strength => sub { return shift->default_value }, }, > > ) > > ); > > apply_all_roles( > > $self, > > > > Moose::Meta::Role->create_anon_role( > > attributes => { > > default_value => { > > is => 'ro', > > isa => 'Int', > > required => 1, > > default => $self->default2, > > }, > > }, > > methods => > > { Weapon_strength => sub { return shift->default_value }, }, > > ) > > ); > > }; > > > > package main; > > for ( my $i = 1 ; $i <= 10000 ; $i++ ) { > > my $def1 = int( rand(100) ); > > my $def2 = int( rand(100) ); > > my $test = Test::Attribute->new( { default1 => $def1, default2 =>
> $def2
> > } ); > > print "User $i has armor: " . $test->Armor_strength . " and weapon " . > > $test->Weapon_strength . "\n"; > > } > > > > 1; > > > > This works, and does indeed leak memory. > > Hopefully I can find a way to make this work without the memory leak. > >
> >
> > 2011/2/14 Hans Dieter Pearcey via RT < > > bug-MooseX-Role-Parameterized@rt.cpan.org> > >
> >> <URL: https://rt.cpan.org/Ticket/Display.html?id=65709 > > >> > >> On Mon Feb 14 10:52:08 2011, j.bonte@legian.nl wrote:
> >>> The role is applied twice to each instance of a new Attribute using > >>> different values for each attribute. > >>> But when the attribute goes out of scope the memory is not cleared.
> >> > >> Using MXRP gives you anonymous roles. Does this happen with regular > >> anonymous roles (e.g. Moose::Meta::Role->create_anon_role)? Looking at > >> the code, I think it may be a bug in Moose rather than in MXRP. > >>
> >
> > >