Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

Ovid
  (email not shown publicly)
http://publius-ovidius.livejournal.com/
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Tuesday September 09, 2008
03:35 AM

Where Did Those Leaks Come From?

[ #37394 ]

Tracking down memory leaks is no fun and frankly, our application is leaking like a stuck pig. In the process of trying to track all of this down, I wrote and submitted a little change for Devel::Object::Leak. This change lets you add callbacks to a global bless. So right now I want to know where my schema objects are being created:

package leaks;

use Data::Dumper::Simple;
$Data::Dumper::Indent   = 1;
$Data::Dumper::Sortkeys = 1;

use Devel::Leak::Object GLOBAL_bless => sub {
    my ($reference, $class) = @_;
    return unless $class && $class->isa('Pips3::Schema');
    my ($package, $file, $line) = caller(2);

    warn Dumper($package, $file, $line, $class);
    warn $/;
};

1;

And then I run a test:

perl -Mleaks t/acceptance.t t/acceptance/import/import_id.yml

Then I get a handy list of where all of those things are getting instantiated (trimmed for clarity):

$package = 'DBIx::Class::Schema';
$file = '...deps/lib/perl5//DBIx/Class/Schema.pm';
$line = 707;
$class = 'Pips3::Schema';

$package = 'DBIx::Class::Schema';
$file = '...deps/lib/perl5//DBIx/Class/Schema.pm';
$line = 589;
$class = 'Pips3::Schema';

$package = 'Catalyst::Model::DBIC::Schema';
$file = '...deps/lib/perl5//Catalyst/Model/DBIC/Schema.pm';
$line = 288;
$class = 'Pips3::Schema';

Well, that told me some of what I needed to know, but not enough. However now that I can add callbacks to bless, I can dump stack traces and really figure out what's going on.

(What's really interesting is the discovery that there are three schema objects being created here, when I thought there should only be only or two).

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Perhaps you'll find Test::Weaken helpful. There's one routine, poof(). You give it a subroutine that creates your object, it runs the subroutine and frees the return values, then examines them to see which haven't actually been freed.

    This sounds contradictory, but the trick Test::Weaken uses is weak references -- that way you try to free something, but still have a reference to anything that didn't get freed. Most useful for you might be that poof() returns a list of the objects which didn't get freed

  • One thing that strikes me as curious is that you want to hook the global, instead of just Hook::LexWrap'ing the specific new method. It does seem a bit like overkill.

    Adam K