Mercurial > pub > Impl
comparison Lib/IMPL/Profiler/Memory.pm @ 194:4d0e1962161c
Replaced tabs with spaces
IMPL::Web::View - fixed document model, new features (control classes, document constructor parameters)
author | cin |
---|---|
date | Tue, 10 Apr 2012 20:08:29 +0400 |
parents | cd1ff7029a63 |
children |
comparison
equal
deleted
inserted
replaced
193:8e8401c0aea4 | 194:4d0e1962161c |
---|---|
6 | 6 |
7 my %listeners; | 7 my %listeners; |
8 my $trapped; | 8 my $trapped; |
9 | 9 |
10 BEGIN { | 10 BEGIN { |
11 $trapped = 0; | 11 $trapped = 0; |
12 } | 12 } |
13 | 13 |
14 sub import { | 14 sub import { |
15 if (not $trapped) { | 15 if (not $trapped) { |
16 *CORE::GLOBAL::bless = sub { | 16 *CORE::GLOBAL::bless = sub { |
17 $_[1] |= caller unless $_[1]; | 17 $_[1] |= caller unless $_[1]; |
18 my $ref = CORE::bless $_[0],$_[1]; | 18 my $ref = CORE::bless $_[0],$_[1]; |
19 | 19 |
20 $_->track($ref) foreach values %listeners; | 20 $_->track($ref) foreach values %listeners; |
21 | 21 |
22 return $ref; | 22 return $ref; |
23 }; | 23 }; |
24 $trapped = 1; | 24 $trapped = 1; |
25 } | 25 } |
26 } | 26 } |
27 | 27 |
28 sub _ConnectListener { | 28 sub _ConnectListener { |
29 my ($self,$listener) = @_; | 29 my ($self,$listener) = @_; |
30 | 30 |
31 die "Invalid listener" unless ref $listener; | 31 die "Invalid listener" unless ref $listener; |
32 | 32 |
33 $listeners{refaddr($listener)} = $listener; | 33 $listeners{refaddr($listener)} = $listener; |
34 } | 34 } |
35 | 35 |
36 sub _RemoveListener { | 36 sub _RemoveListener { |
37 my ($self,$listener) = @_; | 37 my ($self,$listener) = @_; |
38 | 38 |
39 die "Invalid listener" unless ref $listener; | 39 die "Invalid listener" unless ref $listener; |
40 | 40 |
41 delete $listeners{refaddr($listener)}; | 41 delete $listeners{refaddr($listener)}; |
42 } | 42 } |
43 | 43 |
44 sub Monitor { | 44 sub Monitor { |
45 my ($self,$code) = @_; | 45 my ($self,$code) = @_; |
46 | 46 |
47 my $data = IMPL::Profiler::Memory::Data->new(); | 47 my $data = IMPL::Profiler::Memory::Data->new(); |
48 | 48 |
49 $data->Monitor($code); | 49 $data->Monitor($code); |
50 | 50 |
51 return $data; | 51 return $data; |
52 } | 52 } |
53 | 53 |
54 package IMPL::Profiler::Memory::Data; | 54 package IMPL::Profiler::Memory::Data; |
55 use parent qw(IMPL::Object::Fields); | 55 use parent qw(IMPL::Object::Fields); |
56 | 56 |
58 use Scalar::Util qw(refaddr weaken isweak); | 58 use Scalar::Util qw(refaddr weaken isweak); |
59 | 59 |
60 use fields qw( objects counter); | 60 use fields qw( objects counter); |
61 | 61 |
62 sub CTOR { | 62 sub CTOR { |
63 my $this = shift; | 63 my $this = shift; |
64 $this->{objects} = []; | 64 $this->{objects} = []; |
65 $this->{counter} = 0; | 65 $this->{counter} = 0; |
66 } | 66 } |
67 | 67 |
68 sub track { | 68 sub track { |
69 my $i = scalar @{$_[0]->{objects}}; | 69 my $i = scalar @{$_[0]->{objects}}; |
70 $_[0]->{objects}[$i] = $_[1]; | 70 $_[0]->{objects}[$i] = $_[1]; |
71 weaken($_[0]->{objects}[$i]); | 71 weaken($_[0]->{objects}[$i]); |
72 $_[0]->{counter} ++; | 72 $_[0]->{counter} ++; |
73 } | 73 } |
74 | 74 |
75 sub Purge { | 75 sub Purge { |
76 my $this = shift; | 76 my $this = shift; |
77 | 77 |
78 return $this->{objects} = [ grep defined($_), @{$this->{objects}}]; | 78 return $this->{objects} = [ grep defined($_), @{$this->{objects}}]; |
79 } | 79 } |
80 | 80 |
81 sub Dump { | 81 sub Dump { |
82 my $this = shift; | 82 my $this = shift; |
83 return Data::Dumper->Dump([$this->{objects}]); | 83 return Data::Dumper->Dump([$this->{objects}]); |
84 } | 84 } |
85 | 85 |
86 sub isLeak { | 86 sub isLeak { |
87 my ($this) = @_; | 87 my ($this) = @_; |
88 $this->Purge(); | 88 $this->Purge(); |
89 return ( scalar(@{$this->{objects}}) > 0); | 89 return ( scalar(@{$this->{objects}}) > 0); |
90 } | 90 } |
91 | 91 |
92 sub Monitor { | 92 sub Monitor { |
93 my ($this,$code) = @_; | 93 my ($this,$code) = @_; |
94 | 94 |
95 die "A reference to a subroutine is required" unless ref $code; | 95 die "A reference to a subroutine is required" unless ref $code; |
96 | 96 |
97 IMPL::Profiler::Memory->_ConnectListener($this); | 97 IMPL::Profiler::Memory->_ConnectListener($this); |
98 eval { | 98 eval { |
99 $code->(); | 99 $code->(); |
100 }; | 100 }; |
101 my $err = $@; | 101 my $err = $@; |
102 IMPL::Profiler::Memory->_RemoveListener($this); | 102 IMPL::Profiler::Memory->_RemoveListener($this); |
103 | 103 |
104 die $err if $err; | 104 die $err if $err; |
105 | 105 |
106 return; | 106 return; |
107 } | 107 } |
108 | 108 |
109 | 109 |
110 | 110 |
111 1; | 111 1; |