File Coverage

blib/lib/Memory/Usage.pm
Criterion Covered Total %
statement 6 30 20.0
branch 0 4 0.0
condition 0 3 0.0
subroutine 2 8 25.0
pod 5 5 100.0
total 13 50 26.0


line stmt bran cond sub pod time code
1             package Memory::Usage;
2 1     1   44508 use warnings;
  1         2  
  1         54  
3 1     1   5 use strict;
  1         2  
  1         530  
4              
5             =head1 NAME
6              
7             Memory::Usage - Tools to determine actual memory usage
8              
9             =head1 VERSION
10              
11             Version 0.201
12              
13             =cut
14              
15             our $VERSION = '0.201';
16              
17              
18             =head1 SYNOPSIS
19              
20             use Memory::Usage;
21             my $mu = Memory::Usage->new();
22              
23             # Record amount of memory used by current process
24             $mu->record('starting work');
25              
26             # Do the thing you want to measure
27             $object->something_memory_intensive();
28              
29             # Record amount in use afterwards
30             $mu->record('after something_memory_intensive()');
31              
32             # Spit out a report
33             $mu->dump();
34              
35              
36             =head1 DESCRIPTION
37              
38             This module lets you attempt to measure, from your operating system's
39             perspective, how much memory a process is using at any given time.
40              
41             =head1 METHODS
42              
43             =head2 Class Methods
44              
45             =over 4
46              
47             =item new ( )
48              
49             Creates a new Memory::Usage object. This object will contain usage state as
50             recorded along the way.
51              
52             =back
53              
54             =cut
55              
56             sub new
57             {
58 0     0 1   my ($class) = @_;
59              
60             # TODO: allow pre-sizing of array at construct time so auto-growing
61             # doesn't affect memory usage later on. Probably not a big deal given
62             # that our granularity is pages (4k) and our logged messages are small.
63 0           my $self = [];
64              
65 0           return bless $self, $class;
66             }
67              
68             # Returns
69             # (vsize, rss, shared pages, code pages, data+stack pages)
70             # in kilobytes. Precision is to nearest 4k page.
71             # TODO: Proc::ProcessTable so that we can support non-Linux?
72             my $page_size_in_kb = 4;
73             sub _get_mem_data
74             {
75 0     0     my ($class, $pid) = @_;
76              
77 0 0         sysopen(my $fh, "/proc/$pid/statm", 0) or die $!;
78 0 0         sysread($fh, my $line, 255) or die $!;
79 0           close($fh);
80 0           my ($vsz, $rss, $share, $text, $crap, $data, $crap2) = split(/\s+/, $line, 7);
81 0           return map { $_ * $page_size_in_kb } ($vsz, $rss, $share, $text, $data);
  0            
82             }
83              
84             =head2 Instance Methods
85              
86             =over 4
87              
88             =item record ( $message [, $pid ])
89              
90             Record the memory usage at call time, logging it internally with the provided
91             message. Optionally takes a process ID to record memory usage for, defaulting
92             to the current process.
93              
94             =cut
95              
96             sub record
97             {
98 0     0 1   my ($self, $message, $pid) = @_;
99              
100 0   0       $pid ||= $$;
101              
102 0           push @$self, [
103             time(),
104             $message,
105             $self->_get_mem_data($pid)
106             ];
107             }
108              
109             =item report ( )
110              
111             Generates report on memory usage.
112              
113             =cut
114              
115             sub report
116             {
117 0     0 1   my ($self) = @_;
118              
119 0           my $report = sprintf "%6s %6s (%6s) %6s (%6s) %6s (%6s) %6s (%6s) %6s (%6s)\n",
120             'time',
121             'vsz',
122             'diff',
123             'rss',
124             'diff',
125             'shared',
126             'diff',
127             'code',
128             'diff',
129             'data',
130             'diff';
131              
132 0           my $prev = [ undef, undef, 0, 0, 0, 0, 0 ];
133 0           foreach (@$self) {
134 0           $report .= sprintf "% 6d % 6d (% 6d) % 6d (% 6d) % 6d (% 6d) % 6d (% 6d) % 6d (% 6d) %s\n",
135             ($_->[0] - $self->[0][0]),
136             $_->[2],
137             ($_->[2] - $prev->[2]),
138             $_->[3],
139             ($_->[3] - $prev->[3]),
140             $_->[4],
141             ($_->[4] - $prev->[4]),
142             $_->[5],
143             ($_->[5] - $prev->[5]),
144             $_->[6],
145             ($_->[6] - $prev->[6]),
146             $_->[1];
147 0           $prev = $_;
148             }
149              
150 0           return $report;
151             }
152              
153             =item dump ( )
154              
155             Prints report on memory usage to stderr.
156              
157              
158             =cut
159              
160             sub dump
161             {
162 0     0 1   my ($self) = @_;
163              
164 0           print STDERR $self->report();
165             }
166              
167             =item state ( )
168              
169             Return arrayref of internal state. Returned arrayref contains zero or more
170             references to arrays with the following columns (in order). All sizes are in
171             kilobytes.
172              
173             =over 4
174              
175             =item timestamp (in seconds since epoch)
176              
177             =item message (as passed to ->record())
178              
179             =item virtual memory size
180              
181             =item resident set size
182              
183             =item shared memory size
184              
185             =item text (aka code or exe) size
186              
187             =item data and stack size
188              
189             =back
190              
191             =cut
192              
193             sub state
194             {
195 0     0 1   my ($self) = @_;
196              
197 0           return $self;
198             }
199              
200             =pod
201              
202             =back
203              
204             =head1 AUTHOR
205              
206             Dave O'Neill, C<< >>
207              
208             =head1 BUGS
209              
210             Please report any bugs or feature requests to C, or through
211             the web interface at L. I will be notified, and then you'll
212             automatically be notified of progress on your bug as I make changes.
213              
214              
215             =head1 SUPPORT
216              
217             You can find documentation for this module with the perldoc command.
218              
219             perldoc Memory::Usage
220              
221             You can also look for information at:
222              
223             =over 4
224              
225             =item * RT: CPAN's request tracker
226              
227             L
228              
229             =item * Search CPAN
230              
231             L
232              
233             =back
234              
235              
236             =head1 SEE ALSO
237              
238             =over 4
239              
240             =item * L
241              
242             Iteratively run coderefs (similar to L) and compare their memory
243             usage. Useful for optimizing specific subroutines with large memory usage once
244             you've identified them as memory hogs. Uses same technique for gathering usage
245             information as this module, so accuracy and precision suffer similarly.
246              
247             =item * L
248              
249             Show the size of Perl variables. Also useful for microoptimzations when you
250             know what you're looking for. Looks at Perl internals, so accuracy is good.
251              
252             =back
253              
254              
255             =head1 LICENSE AND COPYRIGHT
256              
257             Copyright 2010 Dave O'Neill.
258              
259             This program is free software; you can redistribute it and/or modify it
260             under the terms of either: the GNU General Public License as published
261             by the Free Software Foundation; or the Artistic License.
262              
263             See http://dev.perl.org/licenses/ for more information.
264              
265             =cut
266              
267             1; # End of Memory::Usage