|
NAMEDevel::LeakGuard::Object - Scoped checks for object leaksVERSIONThis document describes Devel::LeakGuard::Object version 0.06SYNOPSIS# Track a single object use Devel::LeakGuard::Object; my $obj = Foo::Bar->new; Devel::LeakGuard::Object::track($obj); # Track every object use Devel::LeakGuard::Object qw( GLOBAL_bless ); # Track every object, summary at exit use Devel::LeakGuard::Object qw( GLOBAL_bless :at_end ); # Track a block of code, warning on leaks leakguard { # your potentially leaky code here }; # Track a block of code, die on leaks leakguard { # your potentially leaky code here } on_leak => 'die'; DESCRIPTIONThis module provides tracking of objects, for the purpose of detecting memory leaks due to circular references or innappropriate caching schemes.It is derived from, and backwards compatible with Adam Kennedy's Devel::Leak::Object. Any errors are mine. It works by overridding "bless" and adding a synthetic "DESTROY" method to any tracked classes so that it can maintain a count of blessed objects per-class. Object tracking can be enabled:
Tracking an individual objectTrack individual objects like this:use Devel::LeakGuard::Object qw( track ); # Later... track( my $obj = new Foo ); Tracking object leaks in a block of codeTo detect any object leaks in a block of code:use Devel::LeakGuard::Object qw( leakguard ); leakguard { # your code here. }; Tracking global object leaksuse Devel::LeakGuard::Object qw( GLOBAL_bless ); Finding out what leakedIf you use "leakguard" (recommended) then by default a warning is thrown when leaks are detected. You can customise this behaviour by passing options to "leakguard"; see the documentation for "leakguard" for more information.If you use "GLOBAL_bless" or "track" then you can also specify the ":at_end" option use Devel::LeakGuard::Object qw( GLOBAL_bless :at_end ); in which case a summary of leaks will be displayed at program exit. Load early!"Devel::LeakGuard::Object" can only track allocations of objects compiled after it is loaded - so load it as early as possible.What is a leak?This module counts the number of blessed instances of each tracked class. When we talk about a 'leak' what we really mean here is an imbalance in the number of allocated objects across some boundary. Using this definition we see a leak even in the case of expected imbalances.When interpreting the results you need to remember that it may be quite legitimate for certain allocations to live beyond the scope of the code under test. You can use the various options that "leakguard" supports to filter out such legitimate allocations that live beyond the life of the block being checked. PerformanceAs soon as "Devel::LeakGuard::Object" is loaded "bless" is overloaded. That means that "bless" gets a little slower everywhere. When not actually tracking the overloaded "bless" is quite fast - but still around four times slower than the built-in "bless".Bear in mind that "bless" is fast and unless your program is doing a huge amount of blessing you're unlikely to notice a difference. On my machine core bless takes around 0.5 IXS and loading "Devel::LeakGuard::Object" slows that down to around 2 IXS. INTERFACE"leakguard"Run a block of code tracking object creation and destruction and report any leaks at block exit.At its simplest "leakguard" runs a block of code and warns if leaks are found: leakguard { my $foo = Foo->new; $foo->{me} = $foo; # leak }; # Displays this warning: Object leaks found: Class Before After Delta Foo 3 4 1 Detected at foo.pl line 23 If you really don't want to leak you can die instead of warning: leakguard { my $foo = Foo->new; $foo->{me} = $foo; # leak } on_leak => 'die'; If you need to do something more complex you can pass a coderef to the "on_leak" option: leakguard { my $foo = Foo->new; $foo->{me} = $foo; # leak my $bar = Bar->new; $bar->{me} = $bar; # leak again } on_leak => sub { my $report = shift; for my $pkg ( sort keys %$report ) { printf "%s %d %d\n", $pkg, @{ $report->{$pkg} }; } # do something }; In the event of a leak the sub will be called with a reference to a hash. The keys of the hash are the names of classes that have leaked; the values are refs to two-element arrays containing the bless count for that class before and after the block so the example above would print: Foo 0 1 Bar 0 1 Options Other options are supported. Here's the full list:
"leakstate"Get the current allocation counts for all tracked objects. If "GLOBAL_bless" is in force this will include all blessed objects. If you are using the finer-grained tracking tools ("track" and "leakguard") then only allocations that they cover will be included.Returns a reference to a hash with package names as keys and allocation counts as values. "track"Track an individual object. Tracking an object increases the allocation count for its package by one. When the object is destroyed the allocation count is decreased by one. Current allocation counts may be retrieved using "leakstate".If the object is reblessed into a different package the count for the new package will be incremented and the count for the old package decremented. "status"Print out a Devel::Leak::Object style summary of current object allocations. If youuse Devel::LeakGuard::Object qw( GLOBAL_bless :at_end ); then "status" will be called at program exit to dump a summary of outstanding allocations. DEPENDENCIESList::Util, Scalar::Util, Test::Differences, Test::MoreSEE ALSODevel::Leak::ObjectINCOMPATIBILITIESNone reported.BUGS AND LIMITATIONSPlease report any bugs or feature requests to "bug-devel-leaktrack-object@rt.cpan.org", or through the web interface at <http://rt.cpan.org>.AUTHORAndy Armstrong "<andy@hexten.net>"Based on code taken from Adam Kennedy's Devel::Leak::Object which carries this copyright notice: Copyright 2007 Adam Kennedy. Rewritten from original copyright 2004 Ivor Williams. Some documentation also copyright 2004 Ivor Williams. LICENCE AND COPYRIGHTCopyright (c) 2009, Andy Armstrong "<andy@hexten.net>".This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic. POD ERRORSHey! The above document had some coding errors, which are explained below:
Visit the GSP FreeBSD Man Page Interface. |