While writing some code to track down a memory leak, I came up with the 
following program using Moose 0.93. It appears to show a few leaks:

    #!/usr/bin/env perl

    use Modern::Perl;
    use Devel::LeakGuard::Object qw( GLOBAL_bless );
    use Devel::LeakGuard::Object::State;

    my $leakstate;

    BEGIN {
      $leakstate = Devel::LeakGuard::Object::State->new(
        on_leak => sub {
          my $report = shift;
          my @leaks = sort { $b->[1] <=> $a->[1] }    # high refcount first
            map { [ $_ => $report->{$_}[1] ] }    # class, refcount
            keys %$report;
          printf  "%-45s %s\n" => qw/Class Refcount/;
          say "-" x 54;

          foreach my $leak (@leaks) {
            printf "%-50s %d\n" => @$leak;
          }
        }
      );
    }
    {
      package Foo;
      use Moose;
      has me => ( is => 'rw' );
    }
    {
      package Bar;
      use Moose;
      has me => ( is => 'rw' );
    }
    {

      package Baz;
      sub new { bless {} => shift }
    }
    my $foo = Foo->new;
    $foo->me($foo);
    my $bar = Bar->new;
    $bar->me($bar);
    my $baz = Baz->new;

And the output:

    Class                                         Refcount
    ------------------------------------------------------
    Class::MOP::Method::Accessor                       221
    Class::MOP::Attribute                              112
    Class::MOP::Method                                 48
    Class::MOP::Class::Immutable::Class::MOP::Class    43
    Class::MOP::Instance                               32
    Class::MOP::Method::Constructor                    30
    Moose::Meta::TypeConstraint                        19
    Class::MOP::Method::Wrapped                        17
    Class::MOP::Class                                  8
    Moose::Meta::Method::Accessor                      4
    Moose::Meta::TypeConstraint::Parameterizable       3
    Moose::Meta::Class                                 3
    Moose::Meta::Attribute                             3
    Class::MOP::Package                                2
    Moose::Meta::TypeConstraint::Class                 2
    Moose::Meta::Instance                              2
    Bar                                                1
    Config                                             1
    Baz                                                1
    Moose::Meta::TypeConstraint::Registry              1
    Foo                                                1

Our actual application has some of those refcounts in the thousands (it gets 
fun when I throw Catalyst and DBIx::Class into the mix).  Am I just 
misunderstanding this output or does Moose leak and Class::MOP leak?  (I'm 
suspicious because it shows that Baz still has a refcount of one).

Cheers,
Ovid
--
Buy the book         - http://www.oreilly.com/catalog/perlhks/
Tech blog            - http://use.perl.org/~Ovid/journal/
Twitter              - http://twitter.com/OvidPerl
Official Perl 6 Wiki - http://www.perlfoundation.org/perl6

Reply via email to