Mercurial > pub > Impl
view Lib/IMPL/Profiler/Memory.pm @ 189:08015e2803f1
IMPL::Vew::Web - fixed memory leaks, more tests
author | cin |
---|---|
date | Wed, 04 Apr 2012 02:49:45 +0400 |
parents | 029c9610528c |
children | cd1ff7029a63 |
line wrap: on
line source
package IMPL::Profiler::Memory; use strict; use Carp qw(longmess shortmess); use Scalar::Util qw(refaddr weaken isweak); my %listeners; my $trapped; BEGIN { $trapped = 0; } sub import { if (not $trapped) { *CORE::GLOBAL::bless = sub { $_[1] |= caller unless $_[1]; my $ref = CORE::bless $_[0],$_[1]; $_->track($ref) foreach values %listeners; return $ref; }; $trapped = 1; } } sub _ConnectListener { my ($self,$listener) = @_; die "Invalid listener" unless ref $listener; $listeners{refaddr($listener)} = $listener; } sub _RemoveListener { my ($self,$listener) = @_; die "Invalid listener" unless ref $listener; delete $listeners{refaddr($listener)}; } sub Monitor { my ($self,$code) = @_; my $data = IMPL::Profiler::Memory::Data->new(); $data->Monitor($code); return $data; } package IMPL::Profiler::Memory::Data; use parent qw(IMPL::Object::Fields); use Data::Dumper(); use Scalar::Util qw(refaddr weaken isweak); use fields qw( objects ); sub CTOR { my $this = shift; $this->{objects} = []; } sub track { my $i = scalar @{$_[0]->{objects}}; $_[0]->{objects}[$i] = $_[1]; weaken($_[0]->{objects}[$i]); } sub Purge { my $this = shift; return $this->{objects} = [ grep defined($_), @{$this->{objects}}]; } sub Dump { my $this = shift; return Data::Dumper->Dump([$this->{objects}]); } sub isLeak { my ($this) = @_; $this->Purge(); return ( scalar(@{$this->{objects}}) > 0); } sub Monitor { my ($this,$code) = @_; die "A reference to a subroutine is required" unless ref $code; IMPL::Profiler::Memory->_ConnectListener($this); eval { $code->(); }; my $err = $@; IMPL::Profiler::Memory->_RemoveListener($this); die $err if $err; return; } 1;