module MemoryProfiler
Constants
- DEFAULTS
Public Class Methods
Formats data, such as that returned by start , into a printable, readable string.
# File lib/memory-profiler.rb 259 def self.format(data) 260 " Curr. Delta Class\n" + 261 " ----- ----- -----\n" + 262 data.map{|k,c,d| sprintf(" %5d %+5d %s\n", c, d, k.name) }.join 263 end
Generates an instantaneous report on the current Ruby ObjectSpace, saved to a text file at: /tmp/memory_profiler-<pid>-<time>.log
Returns the filename used.
See: start for valid/default options, except that :sort_by may only have the value :current or :none when using report
# File lib/memory-profiler.rb 112 def self.report(opt = {}) 113 opt = DEFAULTS.merge(opt) 114 GC.start if opt[:force_gc] 115 116 data = ObjectSpaceAnalyser.analyse(opt) 117 118 if opt[:sort_by] == :current 119 data = data.to_a.sort_by{|k,v| -v } 120 data = data[0,opt[:limit]] if opt[:limit] > 0 and opt[:limit] < data.length 121 elsif opt[:sort_by] != :none 122 warn "MemoryProfiler: invalid option :sort_by => #{opt[:sort_by].inspect}; using :none" 123 end 124 125 filename = opt[:filename] || "/tmp/memory_profiler-#{Process.pid}-#{Time.now.to_i}.log" 126 File.open(filename, 'w') do |f| 127 data.each {|k,c| f.printf( "%5d %s\n", c, k.name ) } 128 end 129 130 GC.start if opt[:force_gc] 131 filename 132 end
Stops the current analysis, emits the results, and immediately starts a new analysis.
See: stop, start
# File lib/memory-profiler.rb 217 def self.restart(opt = {}) 218 res = self.stop 219 self.start(opt) 220 res 221 end
If a block is given, executes it and returns a summary. Otherwise, starts the analyser, and waits for a call to restart or stop.
Returned data is an array of:
[ [Class, current_usage, usage_delta], ... ]
Options:
:sort_by => :current # how to order classes; :current | :delta | :absdelta | :none :only => [] # list of only classes to scan; if empty, scans all classes :ignore => [] # list of classes to exclude from reports (including sub-classes and modules, but not namespaces) :limit => 20 # how many of the top classes to report (less than 1 means 'all'); only matters if :sort_by is not :none :force_gc => true # if true, forces a garbage collection before and after generating report :string_debug => false # see ObjectSpaceAnalyser#analyse :marshal_size => false # see ObjectSpaceAnalyser#analyse
# File lib/memory-profiler.rb 153 def self.start(opt = {}, &block) 154 opt = DEFAULTS.merge(opt) 155 if block_given? 156 # get pre-block analysis of ObjectSpace 157 GC.start if opt[:force_gc] 158 prev = ObjectSpaceAnalyser.analyse(opt) 159 GC.start if opt[:force_gc] 160 161 yield 162 163 # get post-block analysis of ObjectSpace 164 GC.start if opt[:force_gc] 165 curr = ObjectSpaceAnalyser.analyse(opt) 166 167 # calculate the differences before and after execution 168 data = self._delta(curr, prev, opt) 169 170 # return it 171 GC.start if opt[:force_gc] 172 data 173 else 174 @@start_sync.synchronize(:EX) do 175 raise 'already started' if @@start_data 176 177 GC.start if opt[:force_gc] 178 @@start_data = [ObjectSpaceAnalyser.analyse(opt), opt] 179 GC.start if opt[:force_gc] 180 end 181 self 182 end 183 end
Begins an analysis thread that runs periodically, reporting to a text file at: /tmp/memory_profiler-<pid>.log
Returns the filename used.
Options:
:delay => 60 # number of seconds between summaries :filename => nil # override the generated default
See: start for other options
# File lib/memory-profiler.rb 60 def self.start_daemon(opt = {}) 61 opt = DEFAULTS.merge(opt) 62 filename = opt[:filename] || "/tmp/memory_profiler-#{Process.pid}.log" 63 @@daemon_sync.synchronize(:EX) do 64 raise 'daemon process already running' if @@daemon_thread 65 @@daemon_thread = Thread.new do 66 prev = Hash.new(0) 67 file = File.open(filename, 'w') 68 loop do 69 begin 70 GC.start if opt[:force_gc] 71 curr = ObjectSpaceAnalyser.analyse(opt) 72 data = self._delta(curr, prev, opt) 73 74 file.puts '-'*80 75 file.puts Time.now.to_s 76 data.each {|k,c,d| file.printf( "%5d %+5d %s\n", c, d, k.name ) } 77 78 prev = curr 79 GC.start if opt[:force_gc] 80 rescue ::Exception => err 81 $stderr.puts "** MemoryProfiler daemon error: #{err}", err.backtrace.map{|b| "\t#{b}" } 82 end 83 sleep opt[:delay] 84 end #loop 85 end #Thread.new 86 end 87 filename 88 end
Stops the current analysis and emits the results.
See: start
# File lib/memory-profiler.rb 190 def self.stop 191 prev = nil 192 opt = nil 193 @@start_sync.synchronize(:EX) do 194 raise 'not started' unless @@start_data 195 prev, opt = @@start_data 196 @@start_data = nil 197 end 198 199 # get the current state of affairs 200 GC.start if opt[:force_gc] 201 curr = ObjectSpaceAnalyser.analyse(opt) 202 203 # calculate the differences before and after execution 204 data = self._delta(curr, prev, opt) 205 206 # return it 207 GC.start if opt[:force_gc] 208 data 209 end
Terminates the analysis thread started by start_daemon
# File lib/memory-profiler.rb 93 def self.stop_daemon 94 @@daemon_sync.synchronize(:EX) do 95 raise 'no daemon process running' unless @@daemon_thread 96 @@daemon_thread.kill 97 @@daemon_thread.join 98 @@daemon_thread = nil 99 end 100 self 101 end